Repository navigation
Keep raw database error text out of production 500 responses #413
Copy link
Copy link
Closed
Labels
DevOpsSecuritySecurity, access control, and data exposureSecurity, access control, and data exposurebugSomething isn't workingSomething isn't working
Milestone
Description
Activity
- added a parent issue
on Oct 6, 2026 - added a commit that references this issue
on Oct 6, 2026 - changed the title
[-]Raw database and Prisma error text appears in production 500 responses[/-][+]Keep raw database error text out of production 500 responses[/+]on Oct 6, 2026 - addedSecuritySecurity, access control, and data exposureSecurity, access control, and data exposure
on Oct 6, 2026 Status: fixed in
355502bonclaude/youthful-lovelace-3nvsc6, at the response layer instead of inhandlePrismaError. Not merged or deployed yet.What shipped: outside development,
getErrorResponseinapps/hocuspocus.server/src/lib/errors.tsreturnsInternal server errorfor everyAppErrorwithstatusCode >= 500. Thecodeis unchanged. A non-AppErroralready got that message. 4xx messages are unchanged.apps/hocuspocus.server/API.mddocuments the rule, andtests/integration/documents.test.tsasserts it.Differences from the plan:
- Steps 1 and 4 were not done.
handlePrismaErrorand theRPC failed:callers still put upstream text into the message. The response layer now hides it, so moving it intocauseis not needed. - Step 3 was already in place.
app.onErrorinsrc/index.tslogs the original error withrequestId.handleErrorindocuments.controller.tslogs it without arequestIdfield; the request log line for the same request has it. - The response body has no
requestId. Hono'srequestId()middleware sends it in theX-Request-Idresponse header. - Handlers with their own error shape do not call
getErrorResponse, so this fix does not cover them. The OpenAPI notes list them: email handlers, admin middleware, media-upload guards and link metadata. - Module handlers under
src/modules/callfail()fromsrc/http/envelope.ts, which does not mask. Their 5xx messages are fixed strings, such as the persist-failed text, so they carry no driver text. TheAPI.mdline "every 5xxerror.messageisInternal server error" coversgetErrorResponseonly.
Verify:
cd apps/hocuspocus.server && bun test tests/integration/documents.test.ts.
Generated by Claude Code
- Steps 1 and 4 were not done.
- added 7 commits that reference this issue
on Oct 9, 2026
Metadata
Metadata
Assignees
Labels
DevOpsSecuritySecurity, access control, and data exposureSecurity, access control, and data exposurebugSomething isn't workingSomething isn't working
Summary
handlePrismaErrorwraps the original error message in aDatabaseError, andgetErrorResponsereturns that message to the client in every environment. Onlydetailsis hidden outside development. So production 500 responses can carry Prisma messages, constraint names, host and port text, and non-Prisma messages such as a Supabase RPC error.apps/hocuspocus.serverWhere
handlePrismaError:apps/hocuspocus.server/src/lib/errors.ts:94-101putserror.messageintoDatabaseError(anAppError).getErrorResponse:apps/hocuspocus.server/src/lib/errors.ts:104-115returnsAppError.messagein every environment.permanentlyDeleteDocument(apps/hocuspocus.server/src/api/services/documents.service.ts:950-953) passes "Footprint purge RPC failed: ".apps/hocuspocus.server/src/http/envelope.ts(ok/fail); keep using it (seeapps/hocuspocus.server/CLAUDE.md§HTTP Modules).Fix plan
handlePrismaError, giveDatabaseErrora fixed public message, for example "A database error occurred.", and keep the original ascause.getErrorResponse, outside development, return the fixed message forDatabaseErrorand for any non-AppError. Keep the specific message for 4xxAppErrors that are written for users (validation, not found, forbidden).requestIdon the server, so support can still trace it.RPC failed:) and move the upstream text intocause.Acceptance criteria
requestId, and no driver text.requestId.apps/hocuspocus.serverpass.Related
/healthreturns raw dependency errors (Stop REST /health from leaking error text or taking every /api route down #405).Generated by Claude Code