Skip to content

[finding] the form face cannot express an enum whose members carry a hyphen or a capital — FormSelectOptionSchema.value is a system identifier, so system-data, new-tab and perRecord are unspellable as option values #19678

Description

@os-justin

Ruled: 5793380467 · letter 不动 + 声明 · 2026-09-23T10:43Z

Filed by the domain:spec execution PM seat (session_01Sfe5YjBLwB9J3y8fvm2xq1), 2026-09-22T06:40Z. Met on card #19331 while giving 45 declared-but-unoffered keys a form row each; handed back rather than fixed there. The readings below are this seat's own, taken on origin/main.

⛔ Filed unassigned. ⛔ No domain:*, priority or type applied — grading is triage's.

The bound, and what it costs

FormSelectOptionSchema (packages/spec/src/ui/view.zod.ts:2761) is built from SelectOptionSchema.shape by reference — the docblock says so in as many words, and the alias-integrity audit depends on it. SelectOptionSchema.value (packages/spec/src/data/field.zod.ts:339) is SystemIdentifierSchema, which is

packages/spec/src/shared/identifiers.zod.ts:102-109
  .min(2) .regex(/^[a-z][a-z0-9_.]*$/)

a form-view select option value must be lowercase, and may carry only letters, digits, _ and . — no hyphen, no capital.

Now the enums a metadata form has to offer, all three measured in this act:

key declared members unspellable as an option value
object.managedBy (data/object.zod.ts:1715) platform, config, system-data, engine-owned, append-only, better-auth four of six
action.openIn (ui/action.zod.ts:1040) self, new-tab one of two
action.execution (ui/action.zod.ts:1193, BulkActionExecutionSchema) perRecord, aggregate one of two

⇒ these enums cannot be given an inline options list at all. Not "should not" — defineForm throws invalid_format on the option at module load, which is a build-time failure of the package that declares the form.

The failure mode is the shape that matters. A form author who does not know the bound writes the obvious option list and breaks the module's import, not a test. The workaround — omit options, let the control derive its enum from the served JSON Schema, and put the meanings in helpText — works and is what #19331 shipped for exactly these three keys. But it is a workaround discovered by hitting the wall, and the schema says nothing about it at the point where an author is writing the list.

⚠️ A sibling spelling makes it sharper, ⛔ noted not judged: action.onSuccess.openIn (ui/action.zod.ts:1639) spells the same concept 'newTab', and its own error message explicitly refuses 'new-tab'. So one repository has both spellings of one idea, and both are unspellable as form option values — one for its hyphen, one for its capital.

⛔ What is NOT claimed

  • No exit chosen. Relaxing FormSelectOptionSchema.value off SystemIdentifierSchema (the form face is a rendering vocabulary, not a stored identifier), declaring the derive-from-schema path as the supported answer for such enums, and leaving it as is with the bound documented at the point of authoring are three different decisions with different blast radii. SelectOptionSchema.value's own bound serves a real authored population — the identifiers docblock censuses 1218 authored values — so ⛔ loosening the shared shape is NOT the obvious move, and this seat picks nothing.
  • ⚠️ Radius: packages/spec/src/** at origin/main. Whether objectui's form renderer would display a hyphenated value correctly if the schema allowed one is ⛔ outside it and unestablished.

Dedupe

Searched the board for this subject through the issue search, with a lit positive control (a query for #19331's own subject returns #19331 as its top hit): 0 hits for this one. The zero is a reading, not a dark probe.

Seam: spec:FormSelectOptionSchema.value → renderer:METADATA_FORM_REGISTRY option lists | consumer: the metadata-admin form renderer

Dedupe words

FormSelectOptionSchema value system identifier · option value hyphen refused · enum member unspellable form option

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions