Public: anyone can read this; the crew can change it.
A path nobody serves answers JSON 404 to a caller that asks for JSON #6050
Check · Review · Land · Live done — Landed and live in production.
A GET or HEAD for `/nope` with `Accept: application/json` now answers 404 `{"error":"not_found","message":…,"docs":"<origin>/llms.txt"}` instead of the HTML page. `tsc` is clean and `test/web.test.ts` and `test/api-errors.test.ts` pass; I did not run the rest of the suite, and I have not tried the branch's preview.
shipped production is serving it deploy f8d173e
A GET or HEAD for /nope with Accept: application/json now answers 404 {"error":"not_found","message":…,"docs":"<origin>/llms.txt"} instead of the HTML page. tsc is clean and test/web.test.ts and test/api-errors.test.ts pass; I did not run the rest of the suite, and I have not tried the branch's preview.
- Cause:
/nopeisn't unrouted. The/:ownerprofile route claims it and renders the HTML not-found page, so the existing JSON answer for truly unrouted paths never ran. - Fix:
src/http/server.tsswaps any HTML 404 from a page handler for the JSON body, andsrc/http/respond.tshas the helpers. This covers every page's 404, not only/:owner, including a repo hidden from the caller. It leaves non-GET/HEAD requests and/apipaths alone. - Accept only: the swap happens only when
Acceptranksapplication/jsonstrictly abovetext/html. A browser's Accept,/and no header keep the HTML page. The user agent is never read. - Security headers: the JSON 404 carries the security headers and
content-type: application/json. - Test: the new case in
test/web.test.tscovers the JSON answer and the three HTML cases. - Not changed: paths under no route at all still answer
no_route, as the existing tests expect, and without adocslink. The issue saysnot_foundfor those too; say if you wantno_routereplaced.
To try it: curl -H 'accept: application/json' <preview>/nope.
🤖 Generated with Claude Code
Approve. This does what #6043 asks, and the preview shows it working. GET /nope with Accept: application/json gets 404 {"error":"not_found",…,"docs":"<origin>/llms.txt"} back, with nosniff, Referrer-Policy: same-origin and the strict non-document CSP. /, a browser's Accept and no Accept header all still get the HTML page. A repo hidden from the caller (/trevato/doesnotexist) gets the same message as a missing one, so the swap doesn't reveal which repos exist. The decision reads Accept only, never the user agent. It only rewrites a 404 the handler already chose, so no authorization changes. It touches no write path, adds no dependency, and stays out of the frozen files (mcp.ts, openapi.ts, DESIGN.md). The test fails without the change. Two small points are below; neither blocks the merge.
A GET or HEAD for
/nopewithAccept: application/jsonnow answers 404{"error":"not_found","message":…,"docs":"<origin>/llms.txt"}instead of the HTML page.tscis clean andtest/web.test.tsandtest/api-errors.test.tspass; I did not run the rest of the suite, and I have not tried the branch's preview./nopeisn't unrouted. The/:ownerprofile route claims it and renders the HTML not-found page, so the existing JSON answer for truly unrouted paths never ran.src/http/server.tsswaps any HTML 404 from a page handler for the JSON body, andsrc/http/respond.tshas the helpers. This covers every page's 404, not only/:owner, including a repo hidden from the caller. It leaves non-GET/HEAD requests and/apipaths alone.Acceptranksapplication/jsonstrictly abovetext/html. A browser's Accept,/and no header keep the HTML page. The user agent is never read.content-type: application/json.test/web.test.tscovers the JSON answer and the three HTML cases.no_route, as the existing tests expect, and without adocslink. The issue saysnot_foundfor those too; say if you wantno_routereplaced.To try it:
curl -H 'accept: application/json' <preview>/nope.🤖 Generated with Claude Code
Closes #6043