Skip to content

web: Elicitation form ignores enumNames on string enums (legacy titled enum renders raw values) #1691

Description

@cliffhall

Problem

SchemaForm ignores enumNames on a scalar string enum, so a legacy titled enum renders its raw wire values instead of the human-readable titles. The everything server's elicitation tool sends exactly this shape:

"legacyTitledEnum": {
  "type": "string",
  "title": "Legacy Titled Single Select Enum",
  "description": "Choose your favorite type of pet",
  "enum": ["pet-1", "pet-2", "pet-3", "pet-4", "pet-5"],
  "enumNames": ["Cats", "Dogs", "Birds", "Fish", "Reptiles"],
  "default": "pet-1"
}

The elicitation form shows a Select with options pet-1 … pet-5 rather than Cats … Reptiles. The user has no way to know what they are picking.

Cause

clients/web/src/components/groups/SchemaForm/SchemaForm.tsx:72-84 — the string-enum branch passes data={fieldSchema.enum} straight through, dropping enumNames:

// string with enum
if (fieldSchema.type === "string" && fieldSchema.enum) {
  return (
    <Select
      ...
      data={fieldSchema.enum}

This is inconsistent with the two sibling branches in the same function, which both already map values to titles:

  • array/multi-select (SchemaForm.tsx:169-178) pairs items.enum with items.enumNames into { value, label }[], guarded on the arrays being the same length.
  • string with oneOf (SchemaForm.tsx:88-92) maps consttitle.

The type already supports it — InspectorFormSchema.enumNames?: string[] exists in clients/web/src/utils/jsonUtils.ts:52, annotated "Non-standard legacy support: titles for enum values". Only the scalar branch fails to read it.

Proposed fix

In the string-enum branch, build the data array the same way the multi-select branch does — pair enum with enumNames into { value, label }[] when enumNames is present and its length matches enum, otherwise fall back to the bare enum values. The length guard matters: enumNames is non-standard and a server may send a mismatched or absent array, and a wrong-length zip would mislabel options.

Since the same zip-with-length-guard would then exist in two branches, consider extracting it to a small local helper used by both.

Acceptance criteria

  • A string enum with a valid enumNames renders the titles as option labels while still submitting the underlying enum values (e.g. shows Cats, submits pet-1).
  • A string enum with no enumNames still renders the raw values (no regression).
  • A mismatched-length enumNames falls back to raw values rather than mislabeling.
  • default still preselects correctly (pet-1Cats shown).
  • Unit tests in SchemaForm.test.tsx cover all four cases above; the file already has enumNames coverage for the multi-select path to model.
  • Verified against the everything server's elicitation tool.

Notes

Scope is the web SchemaForm. Worth a look at whether the TUI's elicitation form has the same gap — if so, either widen this issue or file a follow-up.

Metadata

Metadata

Assignees

Labels

v2Issues and PRs for v2

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions