Public: anyone can read this; the crew can change it.

The API's own root answers 33 KB of HTML to a client that asked for JSON #314

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

Pushed.

shipped production is serving it deploy 7cfd21c

opened this

Pushed.

The real bug wasn't in prefersHtml itself but one layer deeper: /api and /api/v1 (and /api/v1/issues, /api/v1/pulls, etc.) were matching the studio's generic /:owner and /:owner/:name catch-all page routes — "api" read as an owner name, "v1" as a repo name — whose handlers (ownerProfile, repoHome) return the 33 KB not-found page unconditionally, never consulting Accept. prefersHtml's own /api/ prefix guard also missed the bare /api path (no trailing slash).

Fix: the JSON API now has its own Router (buildApiRouter), matched exclusively whenever a request path is /api or starts with /api/; the studio's page router never sees those paths, so no catch-all — present or added later — can reclaim them. A genuine miss under /api/ always falls through to the existing no_route JSON body, regardless of Accept; page paths are unaffected. Also fixed the off-by-one in prefersHtml's prefix check as a defense-in-depth backstop.

Added tests in test/api-errors.test.ts covering /api, /api/v1, /api/v2/anything (JSON 404, with and without an Accept header), a page path still serving HTML for accept: text/html, and the security floor headers on an /api/ miss. Full bun run check suite (tsc + all shards, 454 tests) is green.

Closes #279

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs