Measured while converting the remaining content/docs/fields pages for #6138 (PR 2). Filed unassigned, not fixed there — the conversion takes both keys out of the annotated blocks (they would redden them); whether they come back as declared members is this card's question.
Same class as #6140 (RichTextField's rows). Filed as one card rather than one per page, because the two instances are the same defect in the same layer and triage should grade them together.
Instance 1 — dependsOn, read off select field metadata through an as any
packages/fields/src/widgets/SelectField.tsx:98:
constdependsOn=(configasany)?.dependsOn??dependsOnProp;
config is the field metadata. SelectFieldMetadata (packages/types/src/field-types.ts) declares options, multiple, searchable and nothing else of its own; BaseFieldMetadata declares depends_on?: string[] — the snake_case sibling — and no dependsOn. The camelCase spelling is declared only as a widget prop (FieldWidgetComponentProps.dependsOn?: DependsOnInput, widgets/types.ts:191), which is the ?? dependsOnProp half of that same line.
So an author who writes dependsOn on a select field's metadata gets working cascading options in the app and a key no exported metadata type accepts — declared and enforced disagree in the direction that hides. content/docs/fields/select.mdx documented it as a metadata key, which is how it was found.
The sibling widget reads both spellings explicitly: LookupField.tsx:292 is fieldMeta?.depends_on ?? fieldMeta?.dependsOn, so the same concept is reachable under two names there, one declared and one not.
Instance 2 — description on a lookup's static options
LookupFieldMetadata.options is declared as SelectOptionMetadata[]. SelectOptionMetadata declares label, value, color, icon, disabled, visibleWhen — no description.
LookupField.tsx:250 takes those authored options as the widget's own local type:
conststaticOptions: LookupOption[]=fieldMeta?.options||[];
and LookupField.tsx:526 reads the key:
(opt.description&&opt.description.toLowerCase().includes(q))
LookupOption (LookupField.tsx:38) does declare description?: string — but it is a widget-local interface with an open [key: string]: any, and it is not part of @object-ui/fields's published surface (no occurrence in packages/fields/dist/index.d.ts). The assignment above crosses from the declared metadata type to the open local one without a diagnostic because fieldMeta is untyped.
So a lookup's authored option description is real behaviour (it is searched, and recordToOption at :153 produces the same key for fetched options) that the declared option type rejects.
Candidate resolutions — deliberately not decided here
Both instances turn on the same question, and it is the same question #6140 turns on:
- Declare them — add
dependsOn to SelectFieldMetadata (or migrate the widget to the declared depends_on), and description to SelectOptionMetadata. Whether the key belongs in @objectstack/spec's authorable surface is not this repo's call alone. - Remove the reads — treat both as accidental surfaces, and let
depends_on / a description_field cover the need.
Either way the docs follow the code: content/docs/fields/select.mdx and lookup.mdx (converted in #6138 PR 2) name this card instead of documenting the keys, and will document them as metadata only once a type declares them.
Refs: #6140 (same class, rows) · #6138 (the conversion that measured it) · #4631 / #6121 (declared surfaces that disagree with each other).
Generated by Claude Code
Measured while converting the remaining
content/docs/fieldspages for #6138 (PR 2). Filed unassigned, not fixed there — the conversion takes both keys out of the annotated blocks (they would redden them); whether they come back as declared members is this card's question.Same class as #6140 (
RichTextField'srows). Filed as one card rather than one per page, because the two instances are the same defect in the same layer and triage should grade them together.Instance 1 —
dependsOn, read off select field metadata through anas anypackages/fields/src/widgets/SelectField.tsx:98:configis the field metadata.SelectFieldMetadata(packages/types/src/field-types.ts) declaresoptions,multiple,searchableand nothing else of its own;BaseFieldMetadatadeclaresdepends_on?: string[]— the snake_case sibling — and nodependsOn. The camelCase spelling is declared only as a widget prop (FieldWidgetComponentProps.dependsOn?: DependsOnInput,widgets/types.ts:191), which is the?? dependsOnProphalf of that same line.So an author who writes
dependsOnon a select field's metadata gets working cascading options in the app and a key no exported metadata type accepts — declared and enforced disagree in the direction that hides.content/docs/fields/select.mdxdocumented it as a metadata key, which is how it was found.The sibling widget reads both spellings explicitly:
LookupField.tsx:292isfieldMeta?.depends_on ?? fieldMeta?.dependsOn, so the same concept is reachable under two names there, one declared and one not.Instance 2 —
descriptionon a lookup's static optionsLookupFieldMetadata.optionsis declared asSelectOptionMetadata[].SelectOptionMetadatadeclareslabel,value,color,icon,disabled,visibleWhen— nodescription.LookupField.tsx:250takes those authored options as the widget's own local type:and
LookupField.tsx:526reads the key:LookupOption(LookupField.tsx:38) does declaredescription?: string— but it is a widget-local interface with an open[key: string]: any, and it is not part of@object-ui/fields's published surface (no occurrence inpackages/fields/dist/index.d.ts). The assignment above crosses from the declared metadata type to the open local one without a diagnostic becausefieldMetais untyped.So a lookup's authored option description is real behaviour (it is searched, and
recordToOptionat:153produces the same key for fetched options) that the declared option type rejects.Candidate resolutions — deliberately not decided here
Both instances turn on the same question, and it is the same question #6140 turns on:
dependsOntoSelectFieldMetadata(or migrate the widget to the declareddepends_on), anddescriptiontoSelectOptionMetadata. Whether the key belongs in@objectstack/spec's authorable surface is not this repo's call alone.depends_on/ adescription_fieldcover the need.Either way the docs follow the code:
content/docs/fields/select.mdxandlookup.mdx(converted in #6138 PR 2) name this card instead of documenting the keys, and will document them as metadata only once a type declares them.Refs: #6140 (same class,
rows) · #6138 (the conversion that measured it) · #4631 / #6121 (declared surfaces that disagree with each other).Generated by Claude Code