Found while implementing #5068 (retire ObjectGrid's undeclared accessorKey / header tolerance branch). Filed unassigned, not claiming. Baseline: objectui main @ 3e0214c.
Fact
bridgeListView (packages/react/src/spec-bridge/bridges/list-view.ts:22-46) takes a spec-canonicalListView — whose columns are ListColumn, spelled field / label — and down-translates every column into the undeclared spelling before emitting an object-grid node:
function mapColumn(col) {
if (typeof col === 'string') return { accessorKey: col, header: col };
const mapped = {
accessorKey: col.field,
header: col.label ?? col.field,
};
and then, at :166-176:
const columns = (spec.columns ?? []).map(mapColumn);
const node = { type: 'object-grid', id: spec.name, columns, data: spec.data };
So the declared spelling goes in, the undeclared spelling comes out, and ObjectGrid converts it back (ObjectGrid.tsx:1461, const syntheticCol = { field: col.accessorKey, label: col.header, ... }). A round trip through a dialect neither side needs.
ListColumnSchema is a strict Zod object and rejects that spelling by name — measured against the pinned @objectstack/spec@17.0.0:
declared {field,label} -> ACCEPTED
undeclared {accessorKey,header} -> REJECTED
issue: unrecognized_keys path=[] keys=["accessorKey","header"]
Why it matters
It is the only in-repo producer that depends on ObjectGrid's tolerance branch. A census over examples/, content/docs/, apps/, skills/, e2e/ (924 files) found zero authored accessorKey-shaped object-grid columns — every hit belongs to the table / data-table components, or is content/docs/plugins/plugin-grid.mdx prose forbidding the spelling. This bridge is the exception, and it is machine-authored.
Retiring the tolerance branch silently blanks the bridge. Measured by rendering the bridge's own output through ObjectGrid (inline data, two rows), before and after deleting the branch:
BEFORE node.columns=[{"accessorKey":"name","header":"Name"}] headers=["#","Name"] cells rendered
AFTER node.columns=[{"accessorKey":"name","header":"Name"}] headers=["#"] no cells
An object column matching neither spelling falls through to the string-array arm at ObjectGrid.tsx:1672, whose typeof fieldName === 'string' filter drops every object entry — so the whole column set disappears with no error, no warning and no empty header.
Nothing in the repo catches that. The full plugin-grid suite (80 files, 715 tests) stays green with the branch deleted, specBridgeExportFormats.test.tsx included — that file renders bridge output through ObjectGrid but only asserts the export menu, never the columns.
The bridge currently routes spec-canonical views through the poorer path. The accessorKey arm only does type inference; the declared-field arm is the one the source calls "full feature support" — objectDef enrichment (currency, precision, options with colors, relational meta), resolveFieldLabel i18n, primary-field auto-link, hidden filtering, link / action. So a bridged ListView renders with less than an object-grid authored directly, today.
Relationship to the family
Reproduce
sed -n '22,46p;166,176p' packages/react/src/spec-bridge/bridges/list-view.ts
grep -n "accessorKey" packages/react/src/spec-bridge/__tests__/SpecBridge.test.ts # :107, :111 pin the emitted shape
sed -n '1451,1489p' packages/plugin-grid/src/ObjectGrid.tsx # the tolerance branch
Triage
finding, not pm:queue. The direction depends on the same ruling #5068 is waiting on: if the tolerance branch is retired, mapColumn must emit field / label (and SpecBridge.test.ts:107,111 re-pin, plus a changeset for @object-ui/react); if instead the undeclared spelling were ever declared, this site is already correct. Recording the divergence and the blocking direction only.
Found while implementing #5068 (retire ObjectGrid's undeclared
accessorKey/headertolerance branch). Filed unassigned, not claiming. Baseline: objectuimain@ 3e0214c.Fact
bridgeListView(packages/react/src/spec-bridge/bridges/list-view.ts:22-46) takes a spec-canonicalListView— whosecolumnsareListColumn, spelledfield/label— and down-translates every column into the undeclared spelling before emitting anobject-gridnode:and then, at
:166-176:So the declared spelling goes in, the undeclared spelling comes out, and
ObjectGridconverts it back (ObjectGrid.tsx:1461,const syntheticCol = { field: col.accessorKey, label: col.header, ... }). A round trip through a dialect neither side needs.ListColumnSchemais a strict Zod object and rejects that spelling by name — measured against the pinned@objectstack/spec@17.0.0:Why it matters
It is the only in-repo producer that depends on ObjectGrid's tolerance branch. A census over
examples/,content/docs/,apps/,skills/,e2e/(924 files) found zero authoredaccessorKey-shapedobject-gridcolumns — every hit belongs to thetable/data-tablecomponents, or iscontent/docs/plugins/plugin-grid.mdxprose forbidding the spelling. This bridge is the exception, and it is machine-authored.Retiring the tolerance branch silently blanks the bridge. Measured by rendering the bridge's own output through
ObjectGrid(inline data, two rows), before and after deleting the branch:An object column matching neither spelling falls through to the string-array arm at
ObjectGrid.tsx:1672, whosetypeof fieldName === 'string'filter drops every object entry — so the whole column set disappears with no error, no warning and no empty header.Nothing in the repo catches that. The full
plugin-gridsuite (80 files, 715 tests) stays green with the branch deleted,specBridgeExportFormats.test.tsxincluded — that file renders bridge output throughObjectGridbut only asserts the export menu, never the columns.The bridge currently routes spec-canonical views through the poorer path. The
accessorKeyarm only does type inference; the declared-fieldarm is the one the source calls "full feature support" — objectDef enrichment (currency, precision, options with colors, relational meta),resolveFieldLabeli18n, primary-field auto-link,hiddenfiltering,link/action. So a bridgedListViewrenders with less than anobject-gridauthored directly, today.Relationship to the family
ObjectGridSchema.columns上容忍未声明的accessorKey/header拼写 —— 声明类型是 strict 的 ListColumn,#3104 的列身份门禁结构上看不见这条支路 #5068 rules the consumer half (retire the branch). It cannot land alone: the deletion regresses this producer.col.name别名,而唯一在交付前解析列身份的生产者只有 RelatedList #5120 rules the other producers (packages/componentsdata-table adapter +plugin-dashboard). This site is neither —packages/reactis a fourth location, outside both cards' declared file surfaces.Reproduce
Triage
finding, notpm:queue. The direction depends on the same ruling #5068 is waiting on: if the tolerance branch is retired,mapColumnmust emitfield/label(andSpecBridge.test.ts:107,111re-pin, plus a changeset for@object-ui/react); if instead the undeclared spelling were ever declared, this site is already correct. Recording the divergence and the blocking direction only.