Skip to content

[finding] The Error Codes table on content/docs/api/client-sdk.mdx omits VALIDATION_FAILED — the one code the page's own examples branch on #12389

Description

@yinlianghui

Found while landing #12342 (PR #12387), which had to establish what
error.code can actually hold before writing a narrowing for it.

The gap

content/docs/api/client-sdk.mdx has an Error Codes table listing nine
codes: VALIDATION_ERROR, INVALID_QUERY, UNAUTHENTICATED,
PERMISSION_DENIED, RESOURCE_NOT_FOUND, RATE_LIMIT_EXCEEDED,
INTERNAL_ERROR, SERVICE_UNAVAILABLE, NOT_IMPLEMENTED. Every one is a
member of StandardErrorCode (packages/spec/src/api/errors.zod.ts).

VALIDATION_FAILED is not in the table. It is also not in StandardErrorCode
— it is registered in ERROR_CODE_LEDGER
(packages/spec/src/api/error-code-ledger.zod.ts), so
ErrorCode.parse('VALIDATION_FAILED') succeeds and it is a real, live wire
value. Producers emit it from packages/rest (error-response.ts,
rest-server.ts, import-runner.ts) and packages/objectql
(record-validator.ts), and packages/types/src/validation-failure.ts is built
around it.

And it is the code both of the page's own error-handling examples use — one
in a trailing comment, one in a live if (error.code === 'VALIDATION_FAILED')
branch, immediately above the table that does not list it.

Why it matters

A reader who works from the table concludes a per-field validation failure
arrives as VALIDATION_ERROR and writes that branch. It never matches. The
examples are right and the table is incomplete, which is the worse way round:
the table is the part that reads like a reference.

The table also has no column or note distinguishing the closed
StandardErrorCode catalog from the ledger-registered codes, so there is no
place for a reader to learn that the vocabulary is a union of two sets. That is
arguably the real fix rather than adding one row.

Open question for triage

Whether the page should list the ledger codes at all, or state the union and
point at the spec as the authority, is a docs-shape decision — a full ledger
dump on this page would be large and would need to stay in sync. Filed as a
finding rather than a fix so triage can rule on which.

Not in scope

The narrowing defect on the same page's examples (#12342, landed as PR #12387)
and the third unnarrowed catch block (#12388) are separate; this card is only
about the code vocabulary the table publishes.

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions