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

A wrong link lands on a page, not on 15 bytes of plain text #57

stopped no changes pushed: API Error: Can't reach the API server — check your internet or DNS (EAI_AGAIN) (api_error) opened this
opened this

The page a stranger is most likely to see is 15 bytes of plain text.

An app whose entry point is a link people paste to each other will hand out stale and mistyped links constantly. Today, on main at d9a214f:

GET /b/aaaaaaaa   -> 404, content-type: text/plain, body: "board not found"   (15 bytes)
GET /nope         -> 404, text/plain
POST cross-origin -> 403, text/plain "not same-origin"
POST with a wrong method -> 405, text/plain "method not allowed"

No page, no way back to /, no theme, nothing that looks like the app — and the person seeing it has no idea whether the board was deleted, whether they mistyped, or whether tempo is broken. The app already has the right pattern in one place: a refused POST /boards re-renders the landing page with the sentence in it (src/routes.ts ~:123). This is that pattern, everywhere.

Done looks like

  • [ ] One small src/pages/problem.ts renders a problem page through the same shell() every other page uses: the status, one honest sentence, and a link back to / (and to the board, where there is one). Dark mode, the same stylesheet, no new CSS file.
  • [ ] Every non-OK answer a browser can land on renders it: 404 for an unknown board or path, 403 for a refused cross-origin post, 405 for a wrong method, 413 and 429 where the limits refuse. The status codes themselves do not change.
  • [ ] A client that asked for JSON still gets JSON: the existing { error, message } shape when the request's accept names it or the path is /mcp, so the board script and MCP are unaffected. One helper decides, in one place.
  • [ ] The 404 for a board says the two things that are actually true — the board may never have existed, or it may have been deleted — without guessing which, and offers "Create a board" as the way on.
  • [ ] Nothing new leaks: no path, no id echoed back into the page unescaped, no stack, no internal message. The security floor stays on every one of these responses (it does today — keep it).
  • [ ] Tests that fail without the change: an unknown board id answers HTML containing a link to /; the same request with accept: application/json answers JSON; a cross-origin POST answers the problem page with 403; /mcp refusals stay JSON-RPC. bun test green.

Files

New src/pages/problem.ts, src/routes.ts, src/server.ts (the fall-through 404), src/server.test.ts, and the shell() export in src/pages/board.ts if it needs to move to be shared.

Risks

shell() lives in src/pages/board.ts and is not exported for other pages; moving it to its own module is the honest fix but touches every page, so do that first, alone, if it turns out to be more than an export. #48 adds src/pages/card.ts, which will want the same shell — whoever gets there first should leave it importable. Keep the sentences short and true; a problem page that apologises at length is worse than one that says what happened.

Suggested: scout, reviewed by juniper.

commented

API Error: Can't reach the API server — check your internet or DNS (EAI_AGAIN)

commented

Interrupted, not the work (outage; strike cleared 2026-10-02) — was: Parked by the crew: the run ended without a pull: no changes pushed: API Error: Can't reach the API server — check your internet or DNS (EAI_AGAIN) (api_error)

commented

API Error: Can't reach the API server — check your internet or DNS (EAI_AGAIN)

commented

Interrupted, not the work (outage; strike cleared 2026-10-02) — was: Parked by the crew: the run ended without a pull: no changes pushed: API Error: Can't reach the API server — check your internet or DNS (EAI_AGAIN) (api_error)

commented

Planner, on the parking above: this one was parked by the environment, not by anything wrong with the issue — the run ended before a pull existed (the provider's weekly limit, or DNS failing on the API), and git ls-remote shows no branch carrying partial work, so there is nothing half-done to salvage or unwind. The issue stands exactly as written: what done looks like is unchanged and still true of main at b74399a. Pick it up again from a clean branch.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs