Skip to content

docs(schema-reference,skills): object-grid columns key off field, not name (#5352) - #5463

Merged
os-support-ai merged 1 commit into
mainfrom
claude/issue-5352-grid-column-spelling-docs
Aug 21, 2026
Merged

docs(schema-reference,skills): object-grid columns key off field, not name (#5352)#5463
os-support-ai merged 1 commit into
mainfrom
claude/issue-5352-grid-column-spelling-docs

Conversation

@os-support-ai

@os-support-aios-support-ai commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Fixes#5352

Docs half only, per the triage ruling on the card. ObjectGrid's behaviour is not changed here; the fold-vs-filter renderer question stays with #5349 and the wider alias-family ruling with #5120.

What the card said, and what I had to correct

The card describes both shapes as dropped silently — "no throw, no console line". I re-measured on today's main (77f846a8b), after #5349 / PR #5456 landed its diagnostic. That wording is now half true, and the half that survives is the opposite of what the card's ordering suggests.

corpusarray shapedropped?silent today?
content/docs/api/schema-reference.mdmixed (strings, then one object)yes, 1 of 5yes — still completely silent
skills/objectui/guides/page-builder.mdall-objectyes, 3 of 3no — one console.warn naming each column

I have not copied the card's "silently" forward as a blanket claim.

Current behaviour, measured by rendering the doc bytes

Not by reading the type: a throwaway harness extracted the object-grid JSON blocks out of the two files themselvesgit show origin/main:FILE for the before leg, the working tree for the after leg — and rendered each through the real ObjectGrid. The harness was deleted before the commit; only the two corpora and one changeset are in the diff.

content/docs/api/schema-reference.md

BEFORE columns: ["name","email","company","phone",{"name":"status","label":"Status","sortable":true}]
HEADERS ["#","Name","Email","Company","Phone","Actions"]
BODY ["1Open","Ada","ada@x.com","Analytical","555-1",""]
DIAGNOSTICS: 0
AFTER columns: [{"field":"name"},...,{"field":"status","label":"Status","sortable":true}]
HEADERS ["#","Name","Email","Company","Phone","Status","Actions"]
BODY ["1Open","Ada","ada@x.com","Analytical","555-1","Active",""]
DIAGNOSTICS: 0

skills/objectui/guides/page-builder.md

BEFORE columns: [{"name":"name",...},{"name":"price",...},{"name":"status",...}]
HEADERS ["#"] <- row-number column only, zero data columns
BODY ["1Open"]
DIAGNOSTICS: 1
[ObjectUI] ObjectGrid columns: object-grid (objectName: 'products') —
3 of 3 authored columns resolve to nothing, so this grid renders its
row-number column and NO data columns.
• columns[0]: keys seen: `name`, `label`, `type` — no `field` key, ...
AFTER HEADERS ["#","Name","Price","Status"]
BODY ["1Open","Widget","9.50","Live"]
DIAGNOSTICS: 0

Renaming the key was not enough for schema-reference.md

The card frames this as one spelling defect. Rendering showed a second, independent defect in the same array, and this is the part worth reviewing:

columns: ["name","email","company","phone",{ field: "status", ... }]
-> HEADERS ["#","Name","Email","Company","Phone"] <- Status STILL missing

normalizeColumns dispatches the whole array on columns[0]. With a bare string first, the array takes the string[] arm, whose filter is typeof fieldName === 'string' — so a column object standing behind a bare string is dropped whatever it spells. Mixing the two forms is unsupported, and silently so. The example is therefore uniformly ListColumn objects now, and the columns row of the property table names field and states the no-mixing rule.

Contract check

Every corrected column parses under the real strict schema, and every old one is refused by name:

{"field":"status","label":"Status","sortable":true} -> PARSES
{"name":"status","label":"Status","sortable":true} -> REFUSED
invalid_type:["field"] unrecognized_keys:["name"]

sortable and type are kept because ListColumnSchema genuinely declares them (along with width, align, hidden, resizable, wrap, pinned, summary, prefix, link, action).

Sweep, with its counter-probe

A scanner walked every fenced json block in both corpora, JSON-parsed each, recursed for object-grid / view:grid nodes anywhere in the tree, and applied the renderer's own two filters. Grep alone would have missed the two nested grids.

BEFORE json blocks: 35 | parsed: 35 | parse-failed: 0
grid blocks with columns found: 4 <- COUNTER-PROBE
dropped column entries: 4
AFTER json blocks: 35 | parsed: 35 | parse-failed: 0
grid blocks with columns found: 4 <- same probe, still finds them
dropped column entries: 0

Three things make the zero trustworthy: parse failures are reported, never skipped, so no block was silently unread (0 of 35); the counter-probe is the same scan reporting 4 grid blocks it still locates by name after the fix, so the search demonstrably works; and the arm reading for schema-reference.md flipped string to object, confirming the dispatch change landed.

Two adjacent things were checked and deliberately not changed:

Gates

Run on the committed head e8714f782, working tree clean:

gateresult
check:control-bytesOK, 4521 tracked text files
check:skills-pathsOK, 95/96 stated paths resolve
check:doc-typesOK, every documented component type registered
check-changeset-presence.mjsOK, 1 changeset added
check-changeset-no-major.mjsOK

check:doc-snippets was not run: it needs 15 built package dists and reads only fenced ts / tsx snippets. This diff changes zero ts/tsx fences (mechanically: git diff --merge-base over the two files matches 4 json-language fences and zero ts or tsx fences). CI builds and runs it.

Worth noting for the record: no gate in this repo would have caught this.check:doc-types verifies that the type literal object-grid is registered — it is — and check:doc-snippets explicitly excludes schema-key validity of metadata blocks as #5138 shape 1, left unruled on purpose. That blind spot is exactly how both corpora drifted.

Changeset: empty frontmatter — docs and skills only, no package src/ touched, nothing to publish.

Generated by Claude Code


Generated by Claude Code

…ot `name` (#5352)
Two published corpora authored `object-grid` columns in a `name` spelling that
`ObjectGrid` does not read. `ListColumnSchema` (`@objectstack/spec/ui`) is a strict
object whose column-identity key is `field`; `{ name, label }` is refused by name
(`unrecognized_keys: ["name"]`) and contributes no rendered column.
Measured by rendering the doc bytes themselves, before and after:
schema-reference.md headers ["#","Name","Email","Company","Phone","Actions"]
-> headers ["#","Name","Email","Company","Phone","Status","Actions"]
page-builder.md headers ["#"] (row-number column only, zero data columns)
-> headers ["#","Name","Price","Status"]
The schema-reference example needed more than a key rename: it authored a MIXED
array, and `normalizeColumns` dispatches the whole array on `columns[0]`, so a
column object standing behind a bare string is dropped whatever it spells. It is
now uniformly `ListColumn` objects. The property table names `field` and states
the no-mixing rule.
The adjacent `object-form` example is deliberately untouched — `FormField.name` is
that layer's real key, and that adjacency is the documented cause of this defect
family (`packages/core/src/utils/column-identity.ts`).
Renderer behaviour is unchanged; this is the docs half only, per triage.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RV6yuVCxymHYE16PL9vQkE
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants

@os-support-ai@claude