Skip to content

[finding] content/docs/api/error-catalog.mdx lists DUPLICATE_RECORD under Conflict Errors (409) with no note that the wire spelling is UNIQUE_VIOLATION #15631

Description

@baozhoutao

Recorded while fixing #15362 (which corrected the same confusion on content/docs/protocol/kernel/error-handling.mdx). #15362's own body listed this page as not measured, so it is filed rather than fixed there; the #15362 PR touches one file only.

What the page says

content/docs/api/error-catalog.mdx on origin/main 6b8c67778:

  • line 355, under ## Conflict Errors (409): ### DUPLICATE_RECORD — "A record with the same unique key already exists."
  • line 796, the HTTP Status Quick Reference: | 409 | conflict | CONCURRENT_MODIFICATION, DUPLICATE_RECORD, DELETE_RESTRICTED |

UNIQUE_VIOLATION appears nowhere on the page.

What the platform does

Maintainer ruling on #14723 (2026-09-03): a unique-constraint refusal has ONE wire spelling on every route, UNIQUE_VIOLATION; the engine's DuplicateRecordError.code stays DUPLICATE_RECORD in-process only. The translation happens at the REST door — packages/rest/src/error-response.ts:992, structuredCodeAnswer's DuplicateRecordError arm, which answers status: 409 with code: 'UNIQUE_VIOLATION' — and is pinned by packages/rest/src/rest-duplicate-record-arm.test.ts section 1.

So the catalog's 409 conflict section names an in-process code and omits the one a client actually branches on.

Why this is not simply the same fix as #15362

The catalog is a code catalog, not an HTTP body reference: its entries carry Cause / Fix / Retry and no **HTTP Status:** line, so check:error-status-conformance reads them only through the section heading and the quick-reference row. That quick-reference row IS a per-code status claim in that gate's grading, so moving DUPLICATE_RECORD out of it, or adding UNIQUE_VIOLATION to it, changes what the gate reconciles.

Grading needed on whether the catalog should (a) rename the entry as #15362 did, (b) keep DUPLICATE_RECORD and add a sibling UNIQUE_VIOLATION entry naming the in-process / wire split, or (c) stay as-is because it catalogs the vocabulary rather than the wire.

Not measured here

Whether the same distinction is missing from content/docs/references/api/error-code-ledger.mdx (generated) or from any other catalog surface.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions