Skip to content

finding(console): the object preview sample's status.options are bare strings, a shape FieldSchema refuses — masked by the sample's quarantine #6844

Description

@claude

Found while implementing objectui#6647 (re-spelling that sample's lookup target). Filed rather than folded in — the fix needs a content decision, not a mechanical re-spelling.

apps/console/src/preview-samples.ts, the object sample:

{name: 'status',label: 'Status',type: 'select',options: ['Draft','Open','Closed']},

FieldSchema wants option OBJECTS, not bare strings. Measured against the installed @objectstack/spec 17.2.0, on the real sample with its (deliberate) array fields shape lifted to a record so the parse stops short-circuiting:

ObjectStackSchema.safeParse({ objects: [ ...sample, fields: as a record ] })
=> success:false, 3 issues, all invalid_type:
objects.0.fields.status.options.0 "Invalid input: expected object, received string"
objects.0.fields.status.options.1 ... .1
objects.0.fields.status.options.2 ... .2

Positive control on the option shape itself: an empty {} in that array reports exactly two missing members, label and value — so the wanted shape is { label, value }.

Why it is invisible today

The sample is quarantined in apps/console/src/__tests__/preview-samples-spec-valid.test.ts for its array fields shape, and Zod short-circuits at objects.0.fields before it ever descends into a field. So this defect is REPORTED by nothing: the reverse assertion only asks for one issue, and the array shape supplies it forever. objectui#6647's PR extended that ledger row to name this defect in prose, which is where the record currently lives — but prose is not a gate.

The designer cannot read it either

ObjectFieldInspector's readOptions() does String(o?.value ?? '') per entry, so three string options materialise as three BLANK rows in the options editor. The sample that exists to demonstrate a picklist demonstrates an empty one.

Why objectui#6647 did not fix it

That card's fence was the lookup key and the ledger reason, and re-authoring these options means INVENTING the value codes the sample should demonstrate (draft vs Draft vs something else) — an authoring decision about what the worked example teaches, not a rename pinned by existing evidence. Deliberately left for triage.

Not to be confused with

  • The array fields shape on the same sample is DELIBERATE (it covers readFields()'s array branch in the gallery) and must not be "fixed" — see the ledger row's note.
  • objectui#6153 is a different tier (options[].description on lookup in @object-ui/fields); objectui#4356 is globalFilters[].options in a filter surface. Neither reaches this file.

Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions