Skip to content

finding(app-shell): the designer's ViewColumnInspector writes back whichever column spelling it found, so editing a stored accessorKey column re-saves a spelling object-grid no longer renders #5344

Description

@os-support-ai

Found while implementing #5068 (retiring ObjectGrid's undeclared accessorKey / header tolerance branch, and migrating its one in-repo producer bridgeListView). Filed unassigned, not claiming. Observation class — nothing is broken today by this alone.

The fact

packages/app-shell/src/views/metadata-admin/inspectors/ViewColumnInspector.tsx is the designer's scoped editor for a selected view column. It reads column identity through both spellings and, on write, preserves whichever one the stored document already used:

// :64
function colFieldKey(c: ViewColumn): string {
return c.field ?? c.accessorKey ?? '';
}
// :155
const patchIdentity = (updates: Partial<ViewColumn>) => {
const targetField = 'field' in col || !('accessorKey' in col) ? 'field' : 'accessorKey';
const targetLabel = 'label' in col || !('header' in col) ? 'label' : 'header';

Its own header comment names the intent: "the column IDENTITY (field key + label) … round-trip through two shapes: the ObjectStack canonical { field, label } and the legacy TanStack { accessorKey, header }."

Why it is worth recording now

#5068 removes the runtime that made the second shape work. After that PR:

  • creating a column in the designer is already canonical and unaffected — makeColumn (previews/view-column-io.ts:60) emits { field } plus label only when the author's label differs from the machine name;
  • editing a column of a stored view that already carries { accessorKey, header } re-saves it in that spelling. The inspector shows the value (it reads both), the author changes the field key, saves — and the column still does not render in an object-grid, because the spec refuses those keys by name (ListColumnSchema is strict: unrecognized_keys ["accessorKey","header"]) and the renderer no longer tolerates them.

So the editor keeps a dialect alive one layer above the renderer that just gave it up. That is the same declared-vs-read divergence #5068 is about, relocated into the authoring tool — where it is arguably worse, since the tool is the surface that is supposed to teach the correct shape.

Note this is a round-trip only: the inspector never invents the undeclared spelling, it only preserves one it was handed. Whether such documents exist in a real tenant is unmeasured here (the in-repo census for #5068 found zero authored accessorKey-shaped object-grid columns across examples/, content/docs/, apps, skills, e2e and package READMEs; every in-repo occurrence belongs to the table / data-table component, which legitimately owns the key).

The fork, unruled

  1. Normalize on writepatchIdentity always writes { field, label } and drops accessorKey / header when it rewrites the column. The designer then migrates legacy documents by the act of editing them, which is the producer-side unification AGENTS.md #0.1 asks for.
  2. Read both, write canonical, and say so — same as (1) plus a visible note in the inspector that the column was migrated.
  3. Leave it — the round trip is harmless as long as nothing renders those columns, and the spelling dies out with the documents.

(1) matches the disposition #5068 inherited from #3951; (3) is defensible only if no such documents exist, which nobody has measured on real data.

Scope note

Out of scope for #5068, whose granted file surface is packages/plugin-grid + packages/react (packages/app-shell/** explicitly excluded). Same family as #5120 (col.accessorKey || col.name in packages/components / plugin-dashboard) and #5340 (bridgeListView, resolved by #5068's PR). This is the fifth site in that family and the only one that is an editor rather than a renderer or a producer.

Reproduce

sed -n '1,20p;60,70p;150,170p' packages/app-shell/src/views/metadata-admin/inspectors/ViewColumnInspector.tsx
sed -n '60,70p' packages/app-shell/src/views/metadata-admin/previews/view-column-io.ts # create path: canonical

Generated by Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    domain:uiobjectui ui stream: fix lands on the published library or apps — objectui execution seatpm:queue

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions