Measured while re-anchoring objectui#6598 (html-tier list-view columns) on origin/main @ ece68882. Filing, not claiming.
What was measured
Same html-kind page, same data source, same object (opportunity), one variable — whether a host fetches the rows or the grid does:
| page source | data columns rendered |
|---|
object-grid with objectName, no columns (grid owns the fetch) | 5 — Opportunity Name / Stage / Amount / Close Date / Owner |
list-view with objectName, no columns (ListView owns the fetch) | 10 — Id, Opportunity Name, Amount, Stage, Close Date, Owner, Created At, Created By, Updated At, Updated By |
The object schema marked id as hidden: true and the five bookkeeping fields as system (four of them readonly). The first row is the platform's stated default-columns policy; the second is the raw row payload.
Mechanism
ObjectGrid's column derivation has two default branches and checks them in this order:
- inline-data branch — gated on
hasInlineData, which is dataConfig?.provider === 'value', and dataConfig is built as provider:'value' from passedData (the data PROP) before anything else. Its projection is schemaFields || Object.keys(inlineData[0]) — the first row's keys. - object-schema branch — the one carrying the policy the code documents as "Default columns priority (when schema doesn't specify columns)":
highlightFields first, otherwise all schema fields with hidden dropped, readonly system-managed fields dropped, and the remaining system/ownership columns pushed to the end.
Branch 1 returns first and wins whenever rows are present. A host like ListView always passes data — it owns the fetch — so for every object-bound grid reached through ListView, ObjectView, or any other fetching host, branch 2 is unreachable. The branch that knows the object is the one that never runs.
The consequence is not cosmetic: id and the audit columns are exactly what the policy exists to keep off a default list, and the payload's key set is whatever the query happened to return.
Why it is filed rather than fixed
packages/plugin-grid was fenced for this dispatch (held by PR #6670). The half that IS in packages/plugin-list — ListView sending fields: [] for "the author declared no columns", which pinned the projection at zero and made neither branch reachable — is fixed in the PR for objectui#6598. This card is the other half: with that one landed, the defaults now run, and they run on the wrong branch.
Suggested shape (not ruled): when the grid has an objectName and a loaded objectSchema, the schema policy should outrank the row-key derivation; the row-key branch is documented as "Legacy support" and is the right answer only for inline data with no object behind it.
Related: objectui#6598 (the html-tier report this came out of).
Generated by Claude Code
Measured while re-anchoring objectui#6598 (html-tier
list-viewcolumns) onorigin/main@ece68882. Filing, not claiming.What was measured
Same html-kind page, same data source, same object (
opportunity), one variable — whether a host fetches the rows or the grid does:object-gridwithobjectName, no columns (grid owns the fetch)list-viewwithobjectName, no columns (ListView owns the fetch)The object schema marked
idashidden: trueand the five bookkeeping fields assystem(four of themreadonly). The first row is the platform's stated default-columns policy; the second is the raw row payload.Mechanism
ObjectGrid's column derivation has two default branches and checks them in this order:hasInlineData, which isdataConfig?.provider === 'value', anddataConfigis built asprovider:'value'frompassedData(thedataPROP) before anything else. Its projection isschemaFields || Object.keys(inlineData[0])— the first row's keys.highlightFieldsfirst, otherwise all schema fields withhiddendropped, readonly system-managed fields dropped, and the remaining system/ownership columns pushed to the end.Branch 1 returns first and wins whenever rows are present. A host like
ListViewalways passesdata— it owns the fetch — so for every object-bound grid reached throughListView,ObjectView, or any other fetching host, branch 2 is unreachable. The branch that knows the object is the one that never runs.The consequence is not cosmetic:
idand the audit columns are exactly what the policy exists to keep off a default list, and the payload's key set is whatever the query happened to return.Why it is filed rather than fixed
packages/plugin-gridwas fenced for this dispatch (held by PR #6670). The half that IS inpackages/plugin-list—ListViewsendingfields: []for "the author declared no columns", which pinned the projection at zero and made neither branch reachable — is fixed in the PR for objectui#6598. This card is the other half: with that one landed, the defaults now run, and they run on the wrong branch.Suggested shape (not ruled): when the grid has an
objectNameand a loadedobjectSchema, the schema policy should outrank the row-key derivation; the row-key branch is documented as "Legacy support" and is the right answer only for inline data with no object behind it.Related: objectui#6598 (the html-tier report this came out of).
Generated by Claude Code