Problem
Routes call await req.json() with no guard. A client that sends invalid JSON or an empty body gets an unhandled exception and a 500 instead of a 400.
Where
Examples (run rg -n 'await req(uest)?\.json\(\)' app/api for the full list):
- app/api/repos/[id]/rules/route.ts:82
- app/api/repos/[id]/secrets/route.ts:82,153
- app/api/repos/[id]/env-vars/route.ts:254,303,347
- app/api/settings/route.ts:141
- app/api/repos/route.ts:242,309
- app/api/workspaces/route.ts:230
- app/api/models/route.ts:395
- app/api/sandbox/[id]/tree/route.ts:298
Fix
- Create lib/api/parse-json-body.ts exporting parseJsonBody<T>(req): Promise<{ ok: true; body: T } | { ok: false; response: Response }>. It catches the parse error and returns a 400 { error: "Invalid JSON body." }.
- Replace each unguarded call. Keep the change mechanical. Do not add validation logic in the same PR.
Exit criteria
- parseJsonBody has a unit test in tests/unit/ for valid JSON, invalid JSON and an empty body.
- rg -n 'await req(uest)?\.json\(\)' app/api returns only calls inside the helper.
- One existing route test (pick app/api/settings) gains a case asserting 400 on an invalid body. Must fail on main.
- pnpm lint, pnpm typecheck, pnpm test:unit pass.
Out of scope
Schema validation. That is the zod issue.
https://claude.ai/code/session_01SQ4nS96XYRztd5w9QkubPf
Reactions are currently unavailable
Problem
Routes call await req.json() with no guard. A client that sends invalid JSON or an empty body gets an unhandled exception and a 500 instead of a 400.
Where
Examples (run rg -n 'await req(uest)?\.json\(\)' app/api for the full list):
Fix
Exit criteria
Out of scope
Schema validation. That is the zod issue.
https://claude.ai/code/session_01SQ4nS96XYRztd5w9QkubPf