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

A mistyped studio URL gets the forge's page, not a JSON blob #117

shipped production is serving it opened this has it
opened this

Trim a studio URL in the address bar, or follow a link that has moved, and the front door of the forge answers a browser with a JSON blob.

Measured against the deployed forge, with a browser's own Accept header:

GET /trevato/forge/issues/99999   404  text/html  43,927 B   ← the forge's own page
GET /trevato/nosuchrepo           404  text/html  43,911 B   ← the forge's own page
GET /assets/forge-old.css         404  text/html  43,915 B   ← the forge's own page
GET /trevato/forge/tells          404  application/json  70 B  ← {"error":"no_route", …}

Everything that matches a route and finds nothing renders notFoundPage (src/web/chrome.ts:55). A path that matches no route falls through to noRoute (src/http/server.ts:1099, src/http/respond.ts:52) — written for API clients, correct for them, and the one 404 a person is most likely to reach by hand.

Acceptance

  • [ ] A request whose Accept prefers HTML and whose path is not under /api/ gets the forge's own not-found page — same shell, same header, same Go home — with status 404.
  • [ ] An API client is unchanged: /api/…, and anything asking for JSON, still gets {"error":"no_route","message":"no GET route for …"} with the same status and the same wording. A test holds both halves.
  • [ ] The distinction noRoute exists to draw — a typo'd URL is not a missing resource — survives wherever it is still readable; if the HTML page cannot carry it, say so in the pull rather than deleting it quietly.
  • [ ] The security floor is on the HTML response like every other page: CSP, x-content-type-options, referrer-policy.
  • [ ] bun test green.

Files I expect to change

src/http/server.ts (the fallthrough at :1099), src/http/respond.ts or src/web/chrome.ts (whichever ends up owning the choice), test/web.test.ts.

Risks

  • Auth is not resolved yet. The fallthrough runs before resolveAuth, so there is no Ctx to hand notFoundPage. Either resolve auth first for HTML requests — and then say in the pull what that costs on a path that is by definition rare — or render the page from a context built without a viewer. Do not make every request pay for the 404 path.
  • Do not sniff more than Accept. A request that asks for JSON gets JSON, whatever its path.
  • One line below, an unknown app hostname answers new Response("not found") in plain text (src/http/server.ts:1092). That is a different door — a preview host, not the forge — and it is fine to leave it; if you change it too, say why.

Suggested: Torque.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs