Skip to content

fix(rest): strip read decorations before validating a dataset query - #4879

Merged
xuyushun441-sys merged 1 commit into
mainfrom
claude/dashboard-error-testing-m9j66j
Aug 3, 2026
Merged

fix(rest): strip read decorations before validating a dataset query#4879
xuyushun441-sys merged 1 commit into
mainfrom
claude/dashboard-error-testing-m9j66j

Conversation

@xuyushun441-sys

Copy link
Copy Markdown
Contributor

The bug

Every widget on every dataset-bound dashboard failed:

Dataset query failed: 400 Bad Request — Invalid dataset definition.

Reproduced in a real browser at
/_console/apps/com.example.showcase/dashboard/showcase_ops_dashboard — all 8
widgets, KPI tiles and charts alike.

Root cause

POST /analytics/dataset/query resolves a saved datasetName through
getMetaItems, and the metadata READ path stamps its spec-validation verdict
_diagnostics onto every document it serves. Since #4001 closed the metadata
schemas, DatasetSchema.parse() rejects unrecognized keys instead of
dropping them — so the route handed a served document straight back to the
schema that produced it and got unrecognized_keys: ["_diagnostics"].

The 400 blamed the author for a key the server itself had just added. The
dataset was never wrong.

This is precisely the failure stripReadDecorations exists to prevent, and the
one spec/kernel/metadata-read-decorations.ts already documents from the
cold-boot flow bind (cloud#971): a served body is not a valid input to the
schema that produced it.
That module's guidance simply hadn't been applied on
this route.

The fix

Strip read decorations before validating.

Applied on both branches, not only the datasetName read: the Studio
dataset preview posts its draft inline, and that draft is the document the
designer GET-loaded — decorations and all. A hand-authored draft never carries
these keys, so the strip is a no-op there.

The ADR-0010 provenance envelope (_packageId, _provenance, _lock, …) is
deliberately not a read decoration and still survives the round-trip — the
tests pin that.

Why it shipped

Regression coverage for the saved-dataset path was the gap: every existing case
in analytics-routes.test.ts passed the dataset inline, so nothing ever
exercised the read. The route's tests now cover resolve-by-name, the inline
decorated draft, the 404, and a genuinely malformed saved dataset (still 400).

Confirmed the new test fails without the fix and passes with it.

Verification

Browser-verified against the showcase app (os dev --ui --seed-admin), signing
in through the real form:

before after
widgets rendering the 400 8 / 8 0 / 8
failed HTTP responses 5 0
console errors 0

showcase_ops_dashboard, showcase_chart_gallery and showcase_revenue_pulse
all render live data after the fix.

pnpm --filter @objectstack/rest test — 577 passed (38 files).

Also in this PR

chore: bump objectui to f5bc4c78be76 (requested alongside the fix) via
scripts/bump-objectui.sh, including the @objectstack/console changeset it
generates from objectui's own declared changesets, and a rebuild of the vendored
console dist at the new pin.


Generated by Claude Code

Every widget on every dataset-bound dashboard failed with
"Dataset query failed: 400 Bad Request — Invalid dataset definition."

POST /analytics/dataset/query resolves a saved `datasetName` through
`getMetaItems`, and the metadata READ path stamps its spec-validation
verdict `_diagnostics` onto every document it serves. Since #4001 closed
the metadata schemas, `DatasetSchema.parse()` rejects unrecognized keys
rather than dropping them — so the route handed a served document back to
the schema that produced it and got `unrecognized_keys: ["_diagnostics"]`.
The 400 blamed the author for a key the server had just added.

This is exactly what `stripReadDecorations` exists to prevent, and the
failure `spec/kernel/metadata-read-decorations.ts` already documents from
the cold-boot flow bind (cloud#971). Strip before validating.

Applied on BOTH branches, not only the `datasetName` read: the Studio
dataset preview posts its draft inline, and that draft is the document the
designer GET-loaded, decorations included. A hand-authored draft never
carries these keys, so the strip is a no-op there. The ADR-0010 provenance
envelope (`_packageId`, `_provenance`, …) is not a read decoration and
still survives.

Regression coverage for the saved-dataset path was the gap that let this
ship — every existing case passed the dataset inline, so nothing exercised
the read. Tests now cover resolve-by-name, the inline decorated draft, the
404, and a genuinely malformed saved dataset (still 400).

Also bumps the vendored console pin to objectui@f5bc4c78be76 via
scripts/bump-objectui.sh, with the changeset it generates.

Verified in a real browser against the showcase app: before, all 8 widgets
of showcase_ops_dashboard rendered the 400; after, all 8 render live data,
with zero failed responses and zero console errors.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QuQBvLsJWuYFAYdkqDbM4N
@vercel

vercel Bot commented Aug 3, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
objectstack Ignored Ignored Aug 3, 2026 12:36pm

Request Review

@github-actions github-actions Bot added documentation Improvements or additions to documentation tests tooling size/m labels Aug 3, 2026
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/rest.

11 hand-written doc(s) reference the affected code and may need an implementation-accuracy re-verification:

  • content/docs/ai/connect-mcp.mdx (via @objectstack/rest)
  • content/docs/api/error-handling-server.mdx (via @objectstack/rest)
  • content/docs/api/index.mdx (via @objectstack/rest)
  • content/docs/permissions/authentication.mdx (via @objectstack/rest)
  • content/docs/plugins/index.mdx (via @objectstack/rest)
  • content/docs/plugins/packages.mdx (via @objectstack/rest)
  • content/docs/protocol/kernel/http-protocol.mdx (via @objectstack/rest)
  • content/docs/protocol/kernel/i18n-standard.mdx (via packages/rest)
  • content/docs/releases/implementation-status.mdx (via @objectstack/rest)
  • content/docs/releases/v12.mdx (via @objectstack/rest)
  • content/docs/releases/v17.mdx (via @objectstack/rest)

Advisory only. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs origin/main → pass the list as args.docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants