Skip to content

docs(driver-sql): uncompilableAggregateFunctionError's 501 now survives to the wire (#7407) - #7480

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-7407-uncompilable-aggregate-docblock
Aug 10, 2026
Merged

docs(driver-sql): uncompilableAggregateFunctionError's 501 now survives to the wire (#7407)#7480
os-zhuang merged 1 commit into
mainfrom
claude/issue-7407-uncompilable-aggregate-docblock

Conversation

@claude

@claude claude Bot commented Aug 10, 2026

Copy link
Copy Markdown
Contributor

Fixes #7407

Comment-only. One paragraph of one docblock in packages/drivers/driver-sql/src/sql-driver.ts. No behaviour, no tests, no changeset — skip-changeset route (per the card; not creating an empty changeset).

What was stale

uncompilableAggregateFunctionError's closing "measured consequence" paragraph said:

on the /data routes mapDataError's generic status passthrough is 4xx-ONLY, so this declared 501 does not survive to the wire — it falls to UNCLASSIFIED_FAULT's 500 INTERNAL_ERROR.

True when written (#5907). PR #7402 closed #5582 and inverted it.

Verification (read, not taken on trust)

Against merged main @ 36237a1:

  • packages/rest/src/rest-server.ts:846if (typeof error?.status === 'number' && error.status >= 400 && error.status < 600). The passthrough is 400-599, not 4xx-only.
  • packages/rest/src/rest-server.ts:872-880 — the >= 500 arm returns { status: error.status, body: { error: INTERNAL_ERROR_MESSAGE, ...(declaresServerFault(error) ? { code: error.code } : {}) } }.
  • packages/types/src/error-leak.ts:113-117declaresServerFault is status >= 500 && typeof code === 'string' && code.length > 0. The driver throws status: 501 + code: 'NOT_IMPLEMENTED', so both halves hold.
  • Nothing above :846 intercepts it: every earlier branch keys on DELETE_RESTRICTED / CONCURRENT_UPDATE / ERR_DATASOURCE_UNAVAILABLE / VALIDATION_FAILED / the capability + access gates / PERMISSION_DENIED / innerMessage / OBJECT_NOT_FOUND / INVALID_FIELD.
  • Pinned end-to-end, not just as a unit: packages/rest/src/rest-5xx-status-passthrough.test.ts:406-415 — "an aggregate the backend cannot compile answers 501 NOT_IMPLEMENTED on the wire", asserting res.statusCode === 501 and res.body === { error: INTERNAL_ERROR_MESSAGE, code: 'NOT_IMPLEMENTED' }.

So: the status and the ADR-0112 code now reach the caller. The prose does not — the 5xx arm drops the message unconditionally and substitutes 'Internal server error'. The card and the dispatch both described only the first half; the new paragraph records both, because the message-drop is the next thing a reader measuring this endpoint will notice, and it is what the paragraph's existing closing ADR-0112 sentence ("what reaches every in-process caller and the operator log") was always about.

The edit

Before:

 * Measured consequence, recorded so it is not rediscovered as a bug: on the
 * `/data` routes `mapDataError`'s generic status passthrough is 4xx-ONLY, so
 * this declared 501 does not survive to the wire — it falls to
 * `UNCLASSIFIED_FAULT`'s `500 INTERNAL_ERROR`. That is a gap in the REST
 * boundary — #5582, which this is the first live producer for — not a reason
 * for the driver to misdescribe the fault as the caller's. The driver's job is
 * to state the condition truthfully at the throw site (ADR-0112), which is also
 * what reaches every in-process caller and the operator log.

After:

 * Measured consequence, recorded so it is not rediscovered as a bug: on the
 * `/data` routes `mapDataError`'s generic status passthrough spans 400-599, so
 * this declared 501 DOES survive to the wire as `501` / `NOT_IMPLEMENTED` —
 * pinned end-to-end by `rest-5xx-status-passthrough.test.ts`. This paragraph
 * read the opposite until #7402 closed #5582: the passthrough was 4xx-ONLY,
 * this was its first live producer, and the status fell to
 * `UNCLASSIFIED_FAULT`'s `500 INTERNAL_ERROR`. What that band does drop is the
 * PROSE — a 5xx body is the generic `Internal server error` — so the driver's
 * job at the throw site is unchanged: state the condition truthfully
 * (ADR-0112), which is what reaches every in-process caller and the operator
 * log.

The ADR-0112 class-2 argument, the #6188/ADR-0049 history, the "class is now EMPTY, kept deliberately" warning, and the catalog-choice rationale are all untouched. The issue pointers (#5582, plus #7402) are kept, now as the history that explains why the paragraph once said the opposite — so a reader measuring a real 501 learns it is correct-by-design instead of having to work out which of the two statements is stale.

Companion grep (positive control, re-run)

$ grep -rn "survive to the wire" . | grep -v '^./.git/'
./packages/drivers/driver-sql/src/sql-driver.ts:713: * this declared 501 does not survive to the wire — it falls to

One hit, this file. No driver-turso companion edit needed — matches triage's finding.

Comment-only self-check

$ git diff -U0 | grep -E '^[+-]' | grep -v '^[+-][+-]'

Emits 17 lines, every one of them * … docblock content. git diff --stat: 1 file, +10 −7.

Gates run locally

Gate Result
eslint packages/drivers/driver-sql/src/sql-driver.ts --no-inline-config pass (exit 0, no output)
pnpm --filter @objectstack/driver-sql typecheck pass (exit 0) — needed turbo run build --filter=@objectstack/driver-sql^... first, since a fresh worktree has no built workspace dist/ type declarations

Per the card, the rest of the gate farm is CI's; it is in_progress at the time of writing.

🤖 Generated with Claude Code

https://claude.ai/code/session_01YcMB8dGrg4WFmpH8JuSRmo


Generated by Claude Code

…es to the wire (#7407)

The docblock's closing "measured consequence" paragraph recorded that
`mapDataError`'s generic status passthrough on the `/data` routes was
4xx-ONLY, so this producer's declared `501` / `NOT_IMPLEMENTED` fell to
`UNCLASSIFIED_FAULT`'s `500 INTERNAL_ERROR`. True when written (#5907),
and #5582 was the right pointer for it.

PR #7402 closed #5582: the passthrough now spans 400-599
(`packages/rest/src/rest-server.ts:846`), and the >=500 arm keeps the
status and — via `declaresServerFault` — the producer's `code`. So the
paragraph asserted the opposite of shipped behaviour, in the direction
that costs the most: a reader measuring a real `501` on the wire had to
work out which of the two was stale.

Replaced with the post-#7402 reading, keeping the paragraph's purpose
(don't rediscover this as a bug) pointed the new way, plus the #5582 /
#7402 history so the flip is legible. Records the half that did not
change: the 5xx band still drops the PROSE unconditionally, so the body
is the generic `Internal server error` and the driver's carefully worded
message reaches only in-process callers and the operator log — which is
what the paragraph's closing ADR-0112 sentence was already about.

Both halves verified against the merged code and pinned end-to-end by
`packages/rest/src/rest-5xx-status-passthrough.test.ts` ("an aggregate
the backend cannot compile answers 501 NOT_IMPLEMENTED on the wire").

The ADR-0112 class-2 argument and the catalog-choice rationale above it
are untouched. Comment-only: no behaviour, no tests, no changeset
(`skip-changeset`).

Fixes #7407
@vercel

vercel Bot commented Aug 10, 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 10, 2026 5:40pm

Request Review

@github-actions

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/driver-sql.

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

  • content/docs/data-modeling/drivers.mdx (via @objectstack/driver-sql)
  • content/docs/getting-started/glossary.mdx (via @objectstack/driver-sql)
  • content/docs/kernel/services-checklist.mdx (via @objectstack/driver-sql)
  • content/docs/plugins/anatomy.mdx (via @objectstack/driver-sql)
  • content/docs/plugins/packages.mdx (via @objectstack/driver-sql)
  • content/docs/protocol/kernel/index.mdx (via @objectstack/driver-sql)
  • content/docs/protocol/kernel/lifecycle.mdx (via @objectstack/driver-sql)
  • content/docs/protocol/objectql/query-syntax.mdx (via @objectstack/driver-sql)

1 release-owned page(s) also reference the affected code. These are read-only:

  • content/docs/releases/implementation-status.mdx (via @objectstack/driver-sql)

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

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.

@os-zhuang os-zhuang added the skip-changeset PR has no user-facing published change; bypasses the changeset gate label Aug 10, 2026 — with Claude
@os-zhuang
os-zhuang marked this pull request as ready for review August 10, 2026 18:19
@os-zhuang
os-zhuang added this pull request to the merge queue Aug 10, 2026
Merged via the queue into main with commit a76a3af Aug 10, 2026
28 of 29 checks passed
@os-zhuang
os-zhuang deleted the claude/issue-7407-uncompilable-aggregate-docblock branch August 10, 2026 18:31
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants