You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[bug] The "Coder needs you" notification deep-links to a route that does not exist — the splat is parsed positionally #344
So coding/repos/<repoId>/summary is read as tab coding with an initialSessionId of the literal string "repos". The repo id and summary are ignored entirely.
That link is on the Coder's "🙋 Coder needs you" notification — the one raised precisely when a run is blocked waiting for a human. So the notification that most needs to land somewhere useful lands on a session id that cannot exist.
#338 (1e4c7f1) fixed the deploy notification by linking a stable parent — /console/instances/:id/coding?builds=<repoId> — rather than a per-run page the product does not have. The same reasoning applies here: link the thing that exists before, during and after the event.
While fixing #338 it also found the notification url column has been stored since migration 0026, returned by SELECT *, and never read by the in-app list — so clicking a notification did nothing at all. That is fixed, which means this broken URL is now reachable where before it was inert. Fixing the producer matters more than it did last week.
Worth checking while you are there
Every other deepLink-style producer in workers/api. Two have now been found wrong by inspection rather than by report, which suggests nothing validates them:
a link is a string built in a Worker,
the routes are declared in a React app,
nothing checks the two agree.
A guard is plausible: the console's route table is enumerable, and the set of link-producing helpers is small. That would make this class fail at build time instead of on a user's phone at the moment they are being asked for help. Judge whether it is worth it — a targeted fix plus a test may be enough.
Acceptance
The "Coder needs you" notification lands on a page that exists and shows the blocked run.
Target: /console/instances/:id/coding/<sessionId> — the shape splatParts[1] was always built for. It satisfies #338's exists-before rule: the coding_sessions row is written by POST /coding/sessions before the workflow is dispatched, listSessions returns it whatever its status, and it outlives the run — so the link works before the Pilot blocks, while it waits, and hours later. It is also where the human actually answers: resolving a handoff is a message sent to that session. An id that no longer resolves falls back to the repo list rather than breaking.
Second broken producer found by the sweep: the agent-loop's "Your agent needs you" pointed at /console/#/instances/<id> — a hash path on a BrowserRouter, so the tap opened the console and stopped wherever the user last was. Now instanceLink(). The other six (deployDeepLink, two board links, résumé knowledge/profile, trigger board, push test) were correct and now go through the same module.
Guard built — judged worth it, since two were found by reading and none by report:
workers/api/src/lib/console-links.ts is the only place under workers/api/src that may build a console link.
console-links.test.ts calls every function that module exports (so a new builder is covered the moment it is written) and checks the result against the console's own route table, store/console/src/lib/routes.ts, imported rather than restated.
The check is not route-existence — that passes both bugs, because instances/:id/* matches any splat and path="*" swallows the rest. It encodes what the router does not police: the instance splat is <tab>/<sessionId>, the tab must be a real surface, a #fragment is never read, and a cross-origin URL cannot move an open tab.
A source scan forbids a /console/… literal anywhere else, so a producer cannot dodge the check by living elsewhere; routes.test.ts holds the table against App.tsx and surfaces.tsx so it cannot drift.
Mutation proving it fires — pointed at the old string, before the fix:
× codingSessionLink() lands on a page that exists
→ /console/instances/inst_1/coding/repos/id_2/summary: carries 4 splat segments but
InstanceDetail parses only <tab>/<sessionId>; "id_2", "summary" is ignored
Not changed: notification rows already in D1 keep the old URL; they route to the Coding tab's repo list rather than breaking.
Activity
fix(api,console): a notification link is a string nothing checked aga…
serge-ivo commentedon Aug 7, 2026
Fixed in b09fabf (CI green, API + Host deployed).
Target:
/console/instances/:id/coding/<sessionId>— the shapesplatParts[1]was always built for. It satisfies #338's exists-before rule: thecoding_sessionsrow is written byPOST /coding/sessionsbefore the workflow is dispatched,listSessionsreturns it whatever its status, and it outlives the run — so the link works before the Pilot blocks, while it waits, and hours later. It is also where the human actually answers: resolving a handoff is a message sent to that session. An id that no longer resolves falls back to the repo list rather than breaking.Second broken producer found by the sweep: the agent-loop's "Your agent needs you" pointed at
/console/#/instances/<id>— a hash path on a BrowserRouter, so the tap opened the console and stopped wherever the user last was. NowinstanceLink(). The other six (deployDeepLink, two board links, résumé knowledge/profile, trigger board, push test) were correct and now go through the same module.Guard built — judged worth it, since two were found by reading and none by report:
workers/api/src/lib/console-links.tsis the only place underworkers/api/srcthat may build a console link.console-links.test.tscalls every function that module exports (so a new builder is covered the moment it is written) and checks the result against the console's own route table,store/console/src/lib/routes.ts, imported rather than restated.instances/:id/*matches any splat andpath="*"swallows the rest. It encodes what the router does not police: the instance splat is<tab>/<sessionId>, the tab must be a real surface, a #fragment is never read, and a cross-origin URL cannot move an open tab./console/…literal anywhere else, so a producer cannot dodge the check by living elsewhere;routes.test.tsholds the table againstApp.tsxandsurfaces.tsxso it cannot drift.Mutation proving it fires — pointed at the old string, before the fix:
Not changed: notification rows already in D1 keep the old URL; they route to the Coding tab's repo list rather than breaking.
fix(api,console): a handoff notification lands on the control that an…
refactor(console): four decisions out of the instance page, and the t…
fix(deploy-watch): the watermark only moves forward, so a stale GitHu…