Repository navigation
fix(rest): a refused json export answers the 400 envelope, not a truncated 200 stream - #27753
Conversation
…cated 200 stream The json export wrote its opening bracket before its first read, and the first write commits the response to a streaming 200, so a query the read refused reached the client as a 200 carrying a lone `[`. The bracket now follows the first read, as csv's first byte does. A successful json export is byte-identical. Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WV4d1cSb5LKsNDntVL6VG
Co-Authored-By: Claude <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016WV4d1cSb5LKsNDntVL6VG
📓 Docs Drift Check1 anchor(s) derived from 1 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run. What this run could not see
Coarse fallback — 19 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin ea6a768bb187d6d57dde0deba4a289a7b3dfb206 && git checkout ea6a768bb187d6d57dde0deba4a289a7b3dfb206
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 34dc09b68df7d37ff8f70ed0dae19fbb1700dd65 fd51a665dbfa698ce3e0e43757549bf8a10c3818 && git checkout -B drift-repro 34dc09b68df7d37ff8f70ed0dae19fbb1700dd65 && git merge --no-ff fd51a665dbfa698ce3e0e43757549bf8a10c3818
node scripts/docs-audit/affected-docs.mjs --json 34dc09b68df7d37ff8f70ed0dae19fbb1700dd65 |
|
domain:server#3 · os-elon-musk · session_016WV4czuTWNgKR22fKv7jia Seat ACCEPT · PR #27753 · head
|
Requested by Elon · project thread
domain:server#3 · os-elon-musk · session_016WV4d1cSb5LKsNDntVL6VG
Fixes #27682
What changes
packages/rest/src/data-action-routes.ts: the json export writes its opening[after the firstfindDataanswers, not before it. One line moved into the read loop (if (format === 'json' && firstChunk) res.write('[')), placed before the zero-row break so an empty export is still[]. Nothing else in the route changes, and the import-job region (fix(rest)!: an async import job for an unregistered object is refused with 404 OBJECT_NOT_FOUND before any job is created #27711) is untouched.packages/rest/src/export-json-refusal-envelope.test.ts(new): pins both halves through the realHonoHttpServer..changeset/27682-json-export-read-first.md: patch for@objectstack/rest.Why
The first
res.writecommits the Hono adapter to a streaming 200. Writing[before the first read meant a query that read refused reached the client as a 200 whose body was a lone[, whileformat=csvanswered the 400 envelope. Triage 6504427279: the json export reads its first page before it writes any byte and answers the same envelope. A refusal on a later page is not widened here.Verification
SqlDriver(SQLite):?search=x&searchFields=nope(the card's repro,400 INVALID_FIELD) and?search=x&searchFields=,(400 VALIDATION_ERROR) answer the same status and body forformat=jsonas forformat=csv. Ablation: with the early write restored, both json rows are red (200); restored, green.page=50, 120 rows) and zero rows answers exactly[+ rows joined by,+](or[]),Content-Type: application/json; charset=utf-8, with the same number of reads. Green on the unfixed code too, so the success path did not move.dispatch-gates --ran: 59 derived families, 58 run green, 1 NOT MEASURED (check:dual-build-cjs-loads, exit 3, needs a whole-tree build).pnpm lintgreen;@objectstack/resttypecheck and full suite green (343 files, 6702 passed) after mergingmain.Out of scope finding:
format=xlsxhas the same early commit. Its workbook writer is created before the first read, and the card's repro answers 200 there too (measured). Not fixed or pinned here; the seat can file it.Clause-②: no
Metadata-protocol: none
Human Minimum
packages/specholds no runtime logic.pnpm lintpasses.main, one pull request.packages/spectouched: its generated artifacts are regenerated and committed. (not touched)content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.🤖 Generated with Claude Code
https://claude.ai/code/session_016WV4d1cSb5LKsNDntVL6VG