Skip to content

docs: add the canonical error-reference registry and completeness check - #234

Merged
ankur-arch merged 3 commits into
mainfrom
feat/error-reference-registry
Aug 25, 2026
Merged

docs: add the canonical error-reference registry and completeness check#234
ankur-arch merged 3 commits into
mainfrom
feat/error-reference-registry

Conversation

@wmadden-electric

@wmadden-electric wmadden-electric commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

Replicates prisma/prisma's error-reference pattern in this repo so the docs site can aggregate the unified CLI's structured errors — and removes the legacy error layer that made a complete registry impossible. Companion web PR follows (it consumes this registry and must merge after this).

The registry and its check

  • docs/reference/error-reference.md — the canonical registry: every NAMESPACE.SUBCODE code in production source across 11 namespaces (AUTH, BRANCH, BUCKET, CLI, FEEDBACK, GIT, INIT, POSTGRES, PROJECT, SERVICE, SKILLS), each entry stating the condition that raises it, the command or boundary, the fix where the source carries one, and its meta fields. Warn-severity diagnostics that ride successful runs are labeled as such.
  • scripts/list-error-codes.mjs — enumerates codes from git-tracked production source (mirror of prisma/prisma's scanner; closed namespace list; json / markdown-skeleton / --verify modes; --root lets the docs repo run it against a checkout). It skips tracked-but-deleted files, so a branch mid-delete reports instead of crashing.
  • pnpm check:error-reference — wired into pr-quality.yml as a required-check job: a new code cannot ship undocumented.
  • docsBaseUrl set on platformCommandFamily and skillsCommandFamily, so emitted errors now carry docsUrl = https://www.prisma.io/docs/cli/error-reference/<CODE> (the docs site redirects that path form to the #<CODE> anchor, same convention the ORM family uses). CLI_DOCS_URL also moves from the docs root to /docs/cli, which now exists.

Structured errors at origin: the legacy layer is gone

A registry is only as honest as the codes it can see, and a scanner reads string literals. The CLI had a second error system underneath — a legacy CliError with flat codes (PROJECT_AMBIGUOUS, DATABASE_API_ERROR) that per-domain boundary mappers rewrote into dotted codes on the way out. Two of those rewrites built codes by concatenation:

  • fromLegacyCliError prefixed SERVICE. onto whatever code it was handed. A --project that matched nothing became SERVICE.PROJECT_AMBIGUOUS through a service command and PROJECT.AMBIGUOUS through a project command — two codes for one condition, and the first appears nowhere in source, so neither the scanner nor the registry nor a caller could know it exists.
  • The API mappers used a server-supplied code as the error code, so a 403 surfaced as PROJECT.forbidden — a lowercase code invented by a remote service. A test had pinned that shape.

Both are deleted, along with the whole legacy layer:

  • Every raise site now constructs CliStructuredError with its registered code directly. packages/cli/src/errors.ts (the CliError class, usageError, authRequiredError, …), next-actions.ts's parallel NextAction type, and the five mapper modules (commands/{project,branch,bucket,postgres,git}/errors.ts) are gone or reduced to real factories.
  • The try { … } catch { const mapped = map…(error) } wrapper in every command handler is gone; structured errors settle themselves.
  • A failed Management API call raises the domain's registered *.API_ERROR with the API's own code and status in meta.apiCode / meta.status, where they are data a caller can read.
  • A 401/403 from an API call no longer mints an *.AUTH_REQUIRED code that never existed in source; it is the domain's API error with meta.status and an auth login next action.
  • The legacy free-text fix is now the first user-choice next action, and nextSteps command strings are run-command actions — the rendering the mappers produced, built at the raise site. Install URLs are open-url actions rather than commands.

docs/product/error-conventions.md loses its pre-dotted "MVP Error Codes" list and its stale JSON envelope example, and states the two rules this PR enforces: assign the code at origin, and treat a server's code as data.

Deliberate remaining duplication

SERVICE.PROJECT_NOT_FOUND survives as its own code: it is authored at a raise site, for the services API refusing a project that had already resolved. That is a different moment from a --project reference matching nothing, which is now PROJECT.NOT_FOUND from every command. Worth a look if you would rather collapse the two.

Verification

  • pnpm check:error-reference — registry and source agree exactly, in both directions
  • pnpm typecheck, pnpm check:grammar, biome clean on touched files
  • Full @prisma/cli test suite green; the tests that pinned PROJECT.forbidden, GIT.AUTH_REQUIRED, PROJECT.AUTH_REQUIRED, and SERVICE.PROJECT_NOT_FOUND for an unmatched --project were pinning the invented codes and now pin the registered ones

🤖 Generated with Claude Code

Mirrors prisma/prisma's error-reference pattern so docs.prisma.io can
aggregate the CLI's structured errors:

- docs/reference/error-reference.md documents all 128 NAMESPACE.SUBCODE
  codes in production source, by namespace, with the condition that
  raises each one
- scripts/list-error-codes.mjs enumerates codes from source (json,
  markdown skeleton, and --verify modes, --root for external checkouts)
- pnpm check:error-reference wired into pr-quality.yml: a new code
  cannot ship undocumented
- the command families now set docsBaseUrl, so emitted errors carry
  docsUrl = https://www.prisma.io/docs/cli/error-reference/<CODE>
  (the docs site redirects the path form to the #<CODE> anchor)
- CLI_DOCS_URL points at /docs/cli now that the unified CLI has its own
  docs section; update-check tests pin the new URL

Known gap, deliberately out of scope: a few boundaries build codes
dynamically (SERVICE.<LEGACY>, GIT.<RAW>, POSTGRES.<RAW>, BUCKET.<RAW>
passthroughs), which a literal scanner cannot enumerate; the registry
intro documents the passthrough rule instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
@coderabbitai

coderabbitai Bot commented Aug 25, 2026

Copy link
Copy Markdown

Warning

Review limit reached

Next included review available in 19 minutes.

View limit details

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 7d10dde9-9117-45e5-b039-010f2b178eac

📥 Commits

Reviewing files that changed from the base of the PR and between 5468362 and 1d2e5c7.

📒 Files selected for processing (77)
  • .github/workflows/pr-quality.yml
  • docs/product/error-conventions.md
  • docs/reference/error-reference.md
  • package.json
  • packages/cli/src/cli-name.ts
  • packages/cli/src/cli.ts
  • packages/cli/src/commands/branch/errors.ts
  • packages/cli/src/commands/branch/list.ts
  • packages/cli/src/commands/bucket/context.ts
  • packages/cli/src/commands/bucket/create.ts
  • packages/cli/src/commands/bucket/delete.ts
  • packages/cli/src/commands/bucket/errors.ts
  • packages/cli/src/commands/bucket/key-create.ts
  • packages/cli/src/commands/bucket/key-delete.ts
  • packages/cli/src/commands/bucket/key-list.ts
  • packages/cli/src/commands/bucket/list.ts
  • packages/cli/src/commands/git/connect.ts
  • packages/cli/src/commands/git/disconnect.ts
  • packages/cli/src/commands/git/errors.ts
  • packages/cli/src/commands/postgres/backup-list.ts
  • packages/cli/src/commands/postgres/backup-restore.ts
  • packages/cli/src/commands/postgres/connection-create.ts
  • packages/cli/src/commands/postgres/connection-delete.ts
  • packages/cli/src/commands/postgres/connection-list.ts
  • packages/cli/src/commands/postgres/connection-rotate.ts
  • packages/cli/src/commands/postgres/context.ts
  • packages/cli/src/commands/postgres/create.ts
  • packages/cli/src/commands/postgres/delete.ts
  • packages/cli/src/commands/postgres/errors.ts
  • packages/cli/src/commands/postgres/list.ts
  • packages/cli/src/commands/postgres/show.ts
  • packages/cli/src/commands/postgres/usage.ts
  • packages/cli/src/commands/project/context.ts
  • packages/cli/src/commands/project/create.ts
  • packages/cli/src/commands/project/delete.ts
  • packages/cli/src/commands/project/env-add.ts
  • packages/cli/src/commands/project/env-delete.ts
  • packages/cli/src/commands/project/env-list.ts
  • packages/cli/src/commands/project/env-shared.ts
  • packages/cli/src/commands/project/env-update.ts
  • packages/cli/src/commands/project/errors.ts
  • packages/cli/src/commands/project/link.ts
  • packages/cli/src/commands/project/list.ts
  • packages/cli/src/commands/project/presentation.ts
  • packages/cli/src/commands/project/rename.ts
  • packages/cli/src/commands/project/show.ts
  • packages/cli/src/commands/project/transfer.ts
  • packages/cli/src/commands/service/errors.ts
  • packages/cli/src/commands/service/target.ts
  • packages/cli/src/commands/skills/family.ts
  • packages/cli/src/controllers/app-env-api.ts
  • packages/cli/src/controllers/app-env-file.ts
  • packages/cli/src/controllers/app-env.ts
  • packages/cli/src/controllers/branch.ts
  • packages/cli/src/controllers/database.ts
  • packages/cli/src/controllers/project.ts
  • packages/cli/src/errors.ts
  • packages/cli/src/legacy/output.ts
  • packages/cli/src/lib/app/env-config.ts
  • packages/cli/src/lib/app/env-errors.ts
  • packages/cli/src/lib/app/env-file.ts
  • packages/cli/src/lib/bucket/provider.ts
  • packages/cli/src/lib/database/provider.ts
  • packages/cli/src/lib/project/provider.ts
  • packages/cli/src/lib/project/resolution.ts
  • packages/cli/src/lib/project/setup.ts
  • packages/cli/src/next-actions.ts
  • packages/cli/tests/branch.test.ts
  • packages/cli/tests/bucket.test.ts
  • packages/cli/tests/database-plan-limit.test.ts
  • packages/cli/tests/git.test.ts
  • packages/cli/tests/postgres.test.ts
  • packages/cli/tests/project-resolution.test.ts
  • packages/cli/tests/project.test.ts
  • packages/cli/tests/service-session.test.ts
  • packages/cli/tests/update-check.test.ts
  • scripts/list-error-codes.mjs

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@pkg-pr-new

pkg-pr-new Bot commented Aug 25, 2026

Copy link
Copy Markdown

Open in StackBlitz

npx https://pkg.pr.new/@prisma/cli@234
npx https://pkg.pr.new/@prisma/cli-engine@234

commit: 1d2e5c7

… layer

The CLI carried two error systems: the engine's structured CliStructuredError,
and an older flat-code CliError that per-domain boundary mappers rewrote into
dotted codes on the way out. Two of those rewrites built codes by
concatenation, which is how codes reached users that exist nowhere in source:

- fromLegacyCliError prefixed SERVICE. onto whatever code it was handed, so an
  unmatched --project was SERVICE.PROJECT_AMBIGUOUS through a service command
  and PROJECT.AMBIGUOUS through a project command — two codes for one
  condition, one of them unlistable and unbranchable.
- The API mappers used the server's own code as the error code, so a 403
  surfaced as PROJECT.forbidden. A test had pinned that shape.

Neither is a documentation problem, so neither is fixed by documenting it.
Every raise site now constructs CliStructuredError with its registered code
directly, and the layer that rewrote them is gone:

- deleted src/errors.ts (CliError, usageError, authRequiredError, ...),
  src/next-actions.ts, and the five mappers under commands/*/errors.ts
- removed the try/catch map-and-rethrow wrapper from every command handler;
  a thrown structured error settles itself
- a failed Management API call raises the domain's registered *.API_ERROR
  with the API's code and status in meta.apiCode / meta.status
- a 401/403 no longer mints an *.AUTH_REQUIRED code that never existed in
  source; it is the domain's API error plus an auth login next action
- the legacy free-text fix is the first user-choice next action and nextSteps
  are run-command actions, built at the raise site; install URLs are open-url
  actions rather than commands

Registry and conventions follow the code: the passthrough rule is deleted
rather than described, two entries with no raise site are removed, and
error-conventions.md states the two rules this enforces — assign the code at
origin, and treat a server's code as data.

The scanner also skips tracked-but-deleted files, so a branch mid-delete
reports instead of crashing.

SERVICE.PROJECT_NOT_FOUND deliberately survives: it is authored at a raise
site for the services API refusing an already-resolved project, which is a
different moment from a --project reference matching nothing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
wmadden-electric added a commit to prisma/web that referenced this pull request Aug 25, 2026
prisma/prisma-cli#234 removed the code-rewriting boundary layer, so the
registry no longer documents a passthrough rule and no longer carries the
two entries that had no raise site. 128 codes -> 126.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
The docs site publishes this page and spell-checks it in US English, so
four British spellings (recognised, unrecognised, recognises) are fixed at
the source rather than dictionaried downstream.

CLI.CONSENT_REQUIRED called consent "structurally undefaultable", an
invented word for a simple fact: consent has no default answer and --yes
does not grant it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
@ankur-arch
ankur-arch merged commit 3be89bd into main Aug 25, 2026
15 checks passed
@ankur-arch
ankur-arch deleted the feat/error-reference-registry branch August 25, 2026 16:10
ankur-arch added a commit to prisma/web that referenced this pull request Aug 25, 2026
* docs: aggregate CLI error codes from prisma/prisma-cli

Extends the error-reference pipeline (generator + daily sync + completeness
check) to a second source repo, following the same pattern used for
prisma/prisma. The CLI gets its own page at /docs/cli/error-reference
because the CLI.* namespace exists in both repos with different meanings
(CLI.PROMPT_REQUIRED collides).

- generate-error-reference.mjs takes --target orm|cli; orm output is
  unchanged
- both workflows also check out prisma/prisma-cli and run its own
  scripts/list-error-codes.mjs to verify page completeness, exactly as
  they do with prisma/prisma's scanner
- the generated CLI page (128 codes) is committed, with a sidebar entry
  under the CLI section's Introduction group
- next.config.mjs redirects the path form …/error-reference/<CODE> to
  the #<CODE> anchor for both the ORM and CLI pages — the CLI engine
  composes docsUrls in path form from a family docsBaseUrl, and the ORM
  family's links were 404ing on this before

Companion PR (must merge first): prisma/prisma-cli#234, which adds the
canonical registry and scanner this consumes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>

* docs: regenerate the CLI error page after the upstream cleanup

prisma/prisma-cli#234 removed the code-rewriting boundary layer, so the
registry no longer documents a passthrough rule and no longer carries the
two entries that had no raise site. 128 codes -> 126.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>

* docs: sync the ORM error reference with prisma/prisma main

The completeness check caught real upstream drift: MIGRATION.PLAN_ORIGIN_UNKNOWN
shipped in prisma/orm#30122 and the page had not been regenerated since.
Also picks up wording changes in three existing entries.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>

* docs: teach the spellchecker the CLI error page's real terms

Two genuine names the dictionary lacked: stricli (the argument parser the
engine wraps) and UNWRITABLE (part of the INIT.CONFIG_UNWRITABLE and
INIT.PACKAGE_JSON_UNWRITABLE codes), alongside the existing UNLOADABLE and
UNPARSEABLE entries.

The page itself is regenerated after prisma/prisma-cli fixed four British
spellings and one invented word at the source, rather than adding those to
the dictionary here.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>

* docs: publish the CLI error page with the site's REST API name

The docs site does not reintroduce "Management API" in prose (see
apps/docs/CLAUDE.md); prisma-cli uses that name because the SDK it calls
through is literally `@prisma/management-api-sdk`, which is right in that
repo. The generator already exists to bridge that kind of mismatch for the
ORM target, so the CLI target gets the same treatment: 13 prose occurrences
become "REST API".

The rewrite skips fenced blocks and inline code spans, so identifiers keep
their real names — the exception apps/docs/CLAUDE.md calls out.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>

* docs: treat every markdown code form as opaque in the generator

The prose rewriter recognized only triple-backtick fences and single-backtick
spans, so a tilde fence or a multi-backtick span would have had its contents
rewritten — the identifiers the rewrite exists to protect.

assertMdxSafe had the same blind spot from the other direction: a brace inside
a tilde fence looked like unescaped MDX and would have failed the build for
text that is only ever displayed.

Both now read one CODE_SEGMENT covering backtick and tilde fences and spans of
any delimiter length, and the rewriter walks matches instead of splitting, so
it no longer depends on the pattern having exactly one capture group.

Verified against both fence styles, one/two/three-backtick spans, and mixed
prose; both pages regenerate byte-identically.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>

---------

Signed-off-by: willbot <w.a.madden+machine@gmail.com>
Signed-off-by: Will Madden <madden@prisma.io>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Co-authored-by: Ankur Datta <64993082+ankur-arch@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants