feat(docs): serve the Prisma Next error reference, with anchors matching emitted docsUrls - #8125
Conversation
Serve the canonical error reference from prisma/prisma main at /docs/orm/next/reference/error-reference. The page is generated by scripts/generate-error-reference.mjs, which adds an explicit [#CODE] anchor to every NAMESPACE.SUBCODE heading so the docsUrl fragments the product emits (raw code, uppercase, with the dot) resolve. A daily sync workflow regenerates the page from prisma/prisma main, and a CI check runs list-error-codes.mjs --verify on every push/PR so the page can never silently miss a shipped code. Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
WalkthroughAdds a generated Prisma error-reference page, a local generator, navigation and spelling configuration, anchor coverage tests, and GitHub Actions workflows that verify and synchronize the documentation. ChangesError reference documentation
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant GitHubActions
participant PrismaRepository
participant DocsRepository
participant Vercel
GitHubActions->>PrismaRepository: checkout main source documentation
GitHubActions->>DocsRepository: run generate:error-reference
GitHubActions->>DocsRepository: verify error-code completeness
GitHubActions->>DocsRepository: commit and push changed documentation
GitHubActions->>Vercel: request deployment hook
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches 💡 1📝 Generate docstrings 💡
🧪 Generate unit tests (beta)
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. Comment |
🍈 Lychee Link Check Report4 links: ✅ All links are working!Full Statistics Table
|
|
The latest updates on your projects. Learn more about Argos notifications ↗︎
|
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (4)
apps/docs/tests/error-reference-anchors.spec.ts (1)
10-12: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value
toHaveTextis strict about anchor decoration inside the heading.Fumadocs heading components often render a child anchor link inside the
h3.toHaveTextcompares the whole normalized text content, so any additional rendered link text makes this assertion fail even though the anchor works. UsetoContainTextto keep the test focused on the id-to-heading mapping.♻️ Suggested change
- await expect(heading).toHaveText("CONTRACT.IDENTIFIER_INVALID"); + await expect(heading).toContainText("CONTRACT.IDENTIFIER_INVALID");🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/docs/tests/error-reference-anchors.spec.ts` around lines 10 - 12, Update the heading assertion in the error-reference anchor test to use a containment text check instead of the strict toHaveText check, while preserving the existing h3 id locator and viewport assertion.apps/docs/scripts/generate-error-reference.mjs (3)
41-53: 🎯 Functional Correctness | 🔵 Trivial | 💤 Low value
assertMdxSafestrips only triple-backtick fences.
markdown.replace(/```[\s\S]*?```/g, "")does not handle fences opened with four or more backticks, or tilde fences. If the upstream file adds such a block that contains{or<Tag, the generator throws and blames the source file, even though the content is valid Markdown. Consider matching the fence marker and closing on the same marker length.♻️ Suggested fence-aware strip
- const withoutCode = markdown.replace(/```[\s\S]*?```/g, "").replace(/`[^`\n]*`/g, ""); + const withoutCode = markdown + .replace(/^(`{3,}|~{3,})[^\n]*\n[\s\S]*?^\1[^\n]*$/gm, "") + .replace(/`[^`\n]*`/g, "");🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/docs/scripts/generate-error-reference.mjs` around lines 41 - 53, Update assertMdxSafe to remove fenced code blocks using a fence-aware pattern that supports backtick or tilde fences of three or more characters and closes only with the same marker length; retain the existing inline-code stripping and hostile-text validation.
105-107: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueUnhandled top-level rejection produces no actionable output.
await loadSource()at module top level rejects with a bare stack trace when the fetch fails or--sourcepoints at a missing file. Wrap the entry point so the script prints the message and exits with a non-zero code. This keeps the sync workflow log readable.♻️ Suggested entry point
-const { mdx, codeCount } = transform(await loadSource()); -writeFileSync(OUTPUT, mdx); -console.log(`Wrote ${OUTPUT} with ${codeCount} error codes.`); +try { + const { mdx, codeCount } = transform(await loadSource()); + writeFileSync(OUTPUT, mdx); + console.log(`Wrote ${OUTPUT} with ${codeCount} error codes.`); +} catch (error) { + console.error(error instanceof Error ? error.message : error); + process.exit(1); +}🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/docs/scripts/generate-error-reference.mjs` around lines 105 - 107, Wrap the top-level generate-error-reference workflow around loadSource, transform, and writeFileSync in error handling that logs the failure message and sets a non-zero process exit code. Preserve the successful output and code-count logging, and ensure failures from both fetching and missing --source files produce readable actionable output.
67-77: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winDo not rewrite code headings inside fenced blocks.
The replace runs while
assertMdxSafe(markdown)has already stripped fenced blocks, but other sources could still contain a### ...line inside a fence. If that happens,Unexpected heading shapeor code-spanned anchor text can be emitted. Exclude fenced regions before applying^### .+$/gm, or update the guard to forbid such source content.Also confirm Fumadocs emits
h3[id="CONTRACT.IDENTIFIER_INVALID"]from the[#CONTRACT.IDENTIFIER_INVALID]suffix, because the Playwright test depends on that custom HTML id.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@apps/docs/scripts/generate-error-reference.mjs` around lines 67 - 77, Update the heading-rewrite flow around the body.replace call so fenced code-block contents are excluded before matching or rewriting ### headings, while preserving code-heading extraction and anchor suffix generation for real headings. Ensure the resulting Fumadocs output still renders the suffix for a code heading as h3[id="CONTRACT.IDENTIFIER_INVALID"], and retain the existing invalid-heading validation outside fenced regions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In @.github/workflows/error-reference-check.yml:
- Around line 8-12: Restrict the pull_request trigger for the error-reference
check workflow to changes under the documentation path that owns the generated
error reference, while retaining the main push trigger. Update the workflow’s on
configuration near the existing pull_request entry; do not alter the upstream
inspection logic or unrelated triggers.
In @.github/workflows/sync-error-reference-docs.yml:
- Around line 14-18: Add job-level contents: read permissions to the sync job in
.github/workflows/sync-error-reference-docs.yml at lines 14-18 and the verify
job in .github/workflows/error-reference-check.yml at lines 13-17; keep the
existing BOT_TOKEN_DOCS_COMMIT push authentication unchanged.
- Around line 24-29: Prevent checkout credentials from being persisted before
running third-party code: in .github/workflows/sync-error-reference-docs.yml at
lines 24-29, add persist-credentials: false to the prisma/prisma checkout; in
.github/workflows/error-reference-check.yml at lines 18-26, add
persist-credentials: false to both the repository checkout and the prisma/prisma
checkout.
- Around line 55-62: Update the “Commit and push” step to pass the repository
token and branch reference through the step’s env configuration, then reference
those environment variables in the git push command instead of directly
interpolating secrets or github.ref_name in the shell script. Preserve the
existing commit and push behavior.
In `@apps/docs/content/docs/orm/next/reference/error-reference.mdx`:
- Line 14: Update the introductory text for the error-reference page to remove
the repository-internal claims about being the canonical source and CI running
on every PR. In the upstream source for this page, retain only reader-facing
publication and anchor details, or remove the corresponding generated clause in
generate-error-reference.mjs so the published page no longer describes
prisma/prisma internals.
---
Nitpick comments:
In `@apps/docs/scripts/generate-error-reference.mjs`:
- Around line 41-53: Update assertMdxSafe to remove fenced code blocks using a
fence-aware pattern that supports backtick or tilde fences of three or more
characters and closes only with the same marker length; retain the existing
inline-code stripping and hostile-text validation.
- Around line 105-107: Wrap the top-level generate-error-reference workflow
around loadSource, transform, and writeFileSync in error handling that logs the
failure message and sets a non-zero process exit code. Preserve the successful
output and code-count logging, and ensure failures from both fetching and
missing --source files produce readable actionable output.
- Around line 67-77: Update the heading-rewrite flow around the body.replace
call so fenced code-block contents are excluded before matching or rewriting ###
headings, while preserving code-heading extraction and anchor suffix generation
for real headings. Ensure the resulting Fumadocs output still renders the suffix
for a code heading as h3[id="CONTRACT.IDENTIFIER_INVALID"], and retain the
existing invalid-heading validation outside fenced regions.
In `@apps/docs/tests/error-reference-anchors.spec.ts`:
- Around line 10-12: Update the heading assertion in the error-reference anchor
test to use a containment text check instead of the strict toHaveText check,
while preserving the existing h3 id locator and viewport assertion.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: d2c65851-fd16-4a46-b139-8b033bcf9d84
📒 Files selected for processing (8)
.github/workflows/error-reference-check.yml.github/workflows/sync-error-reference-docs.ymlapps/docs/content/docs/orm/next/reference/error-reference.mdxapps/docs/content/docs/orm/next/reference/meta.jsonapps/docs/cspell.jsonapps/docs/package.jsonapps/docs/scripts/generate-error-reference.mjsapps/docs/tests/error-reference-anchors.spec.ts
- Restrict GITHUB_TOKEN to contents: read in both workflows. - Set persist-credentials: false on all checkouts, including the prisma/prisma clone whose script the workflows execute. - Pass the bot token and target ref through env instead of shell interpolation in the sync push step. - Run the completeness check on relevant-path PRs plus a daily schedule instead of every PR, so upstream code additions cannot block unrelated PRs while drift on main is still caught daily. - Reword the generated intro sentence that described the source repo's own CI check as if it were this page's. Signed-off-by: willbot <w.a.madden+machine@gmail.com> Signed-off-by: Will Madden <madden@prisma.io>
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/docs/scripts/generate-error-reference.mjs`:
- Around line 60-68: Update the replacement text in the body.replace call to use
the upstream CI wording: state that pnpm check:error-reference runs on every
pull request and fails when a production error code is missing, without claiming
documentation is required before shipping. Keep the existing anchor and
canonical-reference context unchanged.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 5a1629b4-6979-4a44-b6e0-097fb9c3ed29
📒 Files selected for processing (4)
.github/workflows/error-reference-check.yml.github/workflows/sync-error-reference-docs.ymlapps/docs/content/docs/orm/next/reference/error-reference.mdxapps/docs/scripts/generate-error-reference.mjs
🚧 Files skipped from review as they are similar to previous changes (3)
- .github/workflows/error-reference-check.yml
- .github/workflows/sync-error-reference-docs.yml
- apps/docs/content/docs/orm/next/reference/error-reference.mdx
|
@coderabbitai resolve All findings addressed in 10a1a70: token permissions restricted, persist-credentials disabled on all checkouts, token/ref moved into env, PR trigger path-restricted with a daily schedule, and the generator now rewords the source repo's self-referential intro sentence. |
|
If you found this review helpful, would you consider giving us a shout-out on X? Thank you for using CodeRabbit! ✅ Action performedComments resolved and changes approved. |
Every error Prisma Next emits links to its own documentation:
Today that URL 404s. After this PR it renders the full error reference (244 codes) and the browser scrolls straight to the
CONTRACT.IDENTIFIER_INVALIDheading.The decision
We publish the error reference as a generated page, synced from its canonical source —
docs/reference/error-reference.mdonprisma/prismamain— and we never hand-edit it here. Upstream CI already guarantees that file documents every code the product ships, so the docs site treats it as an artifact to ingest, not content to maintain.How it works
The page.
apps/docs/scripts/generate-error-reference.mjsconverts the upstream markdown intocontent/docs/orm/next/reference/error-reference.mdx: it adds the frontmatter this site requires, rewrites repo-relative links to GitHub URLs, and refuses input that would break the MDX build (stray braces/JSX, missing or duplicate codes).The anchors. This is the part most likely to bite. Fumadocs slugifies headings, so
### CONTRACT.IDENTIFIER_INVALIDwould get the idcontractidentifier_invalid— and every emitteddocsUrlfragment (raw code: uppercase, with the dot) would silently fail to scroll. The generator therefore appends Fumadocs' explicit-anchor syntax to each code heading:### CONTRACT.IDENTIFIER_INVALID [#CONTRACT.IDENTIFIER_INVALID]which makes the element id the raw code text. A new Playwright test (
apps/docs/tests/error-reference-anchors.spec.ts) navigates to the fragment URL and asserts the heading has the raw id and lands in the viewport, so a Fumadocs upgrade can't regress this quietly.Staying current. Two independent mechanisms:
sync-error-reference-docs.ymlregenerates the page daily (plus manual andrepository_dispatch: error-reference-updatedtriggers), verifies it, commits as Prismo, and triggers the Vercel deploy hook — the same pattern as the management-API docs sync.error-reference-check.ymlruns upstream's own verifier (list-error-codes.mjs --verify) against the committed page, so even if the sync breaks, drift is caught: on pushes tomain, on PRs that touch the page or its tooling, and on a daily schedule.The generated file is excluded from cspell so upstream wording changes can't fail spellcheck on
main.Looking ahead
When Prisma 8 reaches RC, the ORM
nextchannel becomesv8and this page moves with it to/docs/orm/v8/reference/error-reference; the product then flips one constant in itsdocsUrltemplate.Alternatives considered
🤖 Generated with Claude Code