Filed unassigned while implementing #5378 + #5377 (PR on claude/issue-5378-datasource-wiring-convergence). Deliberately NOT carried in that PR: those two cards are the wiring axis and the key-spelling axis, and this is a third thing — a documented capability that does not exist. Fixing it needs a choice, which is why it is filed rather than patched.
Measured, on origin/main @ 32ef595f4
Rendering the guide's own Step 5 / Step 7 object-grid literals through the real registry with a fake adapter, provider wiring, keys held correct:
| snippet as rendered | find calls | find params |
|---|
{ objectName: 'task', view: 'all', data: { objectSchema } } | 1 | { $select, $top: 50, $skip: 0 } |
{ objectName: 'task' } — view and data both dropped | 1 | { $select, $top: 50, $skip: 0 } |
Identical. Dropping both keys changes nothing that reaches the wire, so neither is read.
Confirming statically:
grep -n "schema\.view" packages/plugin-grid/src/ObjectGrid.tsx — zero hits. view is not in GRID_QUERY_INPUTS either. The only view this system honours is the one inside the spec binding (dataSource: { object, view }), which ElementDataSourceGate resolves against listViews.data is declared as ViewData, the spec's union discriminated on provider (object / api / value / schema). { objectSchema, queryParams } is none of those arms: getDataConfig hands it straight through, hasInlineData is false, and every key inside it is dropped. There is no queryParams read point anywhere in ObjectGrid.
Why it matters
Step 7 asserts two behaviours in prose that the measurements above say do not happen:
The filter and sort arrays defined in the active list view are applied automatically when that view is selected. The $search query param is passed through to your DataSource.find() method.
A reader who builds the view switcher and the search box gets a grid that answers with every record, whichever button they press and whatever they type — the #5349 shape, one level up: the page renders, so nothing looks wrong. This is the getting-started guide, so it is the first thing a new author (very often an AI author) copies.
Step 5 and Step 6 carry the same inert data: { objectSchema: TaskSchema } without a prose claim attached.
What needs deciding
Two legitimate correct forms exist, which is exactly why the PR left this alone:
- Move it into the spec binding —
dataSource: { object: 'task', view: activeView }, which ElementDataSourceGate really does resolve. Teaches the declared surface, but changes runtime behaviour for the reader: a view name the backend does not publish makes the gate render its configuration-error panel where today the reader gets a working (if unfiltered) grid. That trade needs a person. - Spell the view's own keys on the block —
filter / sort are declared in GRID_QUERY_INPUTS and read by ObjectGrid (schemaFilter reaches $filter, schemaSort reaches $orderby), so Step 7 could set them from TaskSchema.list_views[activeView] and drive search through filter instead of the fictional $search passthrough. Smaller blast radius, but it stops teaching saved views on the page that introduces them.
Either way the inert data: { objectSchema } in Steps 5 and 6 should go with it, and the Step 7 prose has to be rewritten to whatever is chosen.
Reproduce
grep -n "view: 'all'\|view: activeView\|queryParams\|objectSchema: TaskSchema" content/docs/guide/building-crud-app.md
grep -n "schema.view" packages/plugin-grid/src/ObjectGrid.tsx # zero hits
grep -n "name: 'data'" packages/plugin-grid/src/index.tsx # ViewData, discriminated on `provider`
Related: #5377 (the key axis on the same five snippets — its filer measured these two keys as inert and set them aside), #5378 (the wiring axis), #5349 (the silent-empty failure mode), #4041 (published vocabulary vs. the renderer's read point, same family).
Generated by Claude Code
Filed unassigned while implementing #5378 + #5377 (PR on
claude/issue-5378-datasource-wiring-convergence). Deliberately NOT carried in that PR: those two cards are the wiring axis and the key-spelling axis, and this is a third thing — a documented capability that does not exist. Fixing it needs a choice, which is why it is filed rather than patched.Measured, on
origin/main@32ef595f4Rendering the guide's own Step 5 / Step 7
object-gridliterals through the real registry with a fake adapter, provider wiring, keys held correct:findcallsfindparams{ objectName: 'task', view: 'all', data: { objectSchema } }{ $select, $top: 50, $skip: 0 }{ objectName: 'task' }—viewanddataboth dropped{ $select, $top: 50, $skip: 0 }Identical. Dropping both keys changes nothing that reaches the wire, so neither is read.
Confirming statically:
grep -n "schema\.view" packages/plugin-grid/src/ObjectGrid.tsx— zero hits.viewis not inGRID_QUERY_INPUTSeither. The onlyviewthis system honours is the one inside the spec binding (dataSource: { object, view }), whichElementDataSourceGateresolves againstlistViews.datais declared asViewData, the spec's union discriminated onprovider(object/api/value/schema).{ objectSchema, queryParams }is none of those arms:getDataConfighands it straight through,hasInlineDatais false, and every key inside it is dropped. There is noqueryParamsread point anywhere inObjectGrid.Why it matters
Step 7 asserts two behaviours in prose that the measurements above say do not happen:
A reader who builds the view switcher and the search box gets a grid that answers with every record, whichever button they press and whatever they type — the #5349 shape, one level up: the page renders, so nothing looks wrong. This is the getting-started guide, so it is the first thing a new author (very often an AI author) copies.
Step 5 and Step 6 carry the same inert
data: { objectSchema: TaskSchema }without a prose claim attached.What needs deciding
Two legitimate correct forms exist, which is exactly why the PR left this alone:
dataSource: { object: 'task', view: activeView }, whichElementDataSourceGatereally does resolve. Teaches the declared surface, but changes runtime behaviour for the reader: aviewname the backend does not publish makes the gate render its configuration-error panel where today the reader gets a working (if unfiltered) grid. That trade needs a person.filter/sortare declared inGRID_QUERY_INPUTSand read byObjectGrid(schemaFilterreaches$filter,schemaSortreaches$orderby), so Step 7 could set them fromTaskSchema.list_views[activeView]and drive search throughfilterinstead of the fictional$searchpassthrough. Smaller blast radius, but it stops teaching saved views on the page that introduces them.Either way the inert
data: { objectSchema }in Steps 5 and 6 should go with it, and the Step 7 prose has to be rewritten to whatever is chosen.Reproduce
Related: #5377 (the key axis on the same five snippets — its filer measured these two keys as inert and set them aside), #5378 (the wiring axis), #5349 (the silent-empty failure mode), #4041 (published vocabulary vs. the renderer's read point, same family).
Generated by Claude Code