fix(host-service): classify worktree-gone terminal failures as NOT_FOUND
Problem
HOST-SERVICE-1N (14 events on 1.20.2): when a workspace's worktree directory is deleted while a terminal pane is still open, every terminal.snapshot poll throws INTERNAL_SERVER_ERROR and the Sentry middleware reports it as a 500 — even though a worktree removed underneath an open terminal is a routine lifecycle condition, not an internal failure.
Root cause
createTerminalSessionInternal (the adoption path under snapshotSession/writeFramedInputToSession) returns the plain string error Workspace worktree no longer exists: <path> when the worktree directory is gone. The router's toTerminalIoError helper name-checks a few known messages ("belong" → FORBIDDEN; "not found"/"not active"/"exited" → NOT_FOUND), but this message matches none of them, so it falls through to the INTERNAL_SERVER_ERROR branch and the dumb 500=report Sentry middleware files it on every poll.
No typed error class crosses this boundary — the runtime returns { error: string } — so the classification has to match the stable message prefix.
Fix
Add a branch to toTerminalIoError that recognizes the Workspace worktree no longer exists prefix and returns NOT_FOUND with cause: { kind: "WORKTREE_GONE" }. The message and all other behaviour are unchanged; genuine unexpected terminal I/O failures still fall through to INTERNAL_SERVER_ERROR and keep reporting.
All terminal procedures that funnel errors through this helper (send, snapshot) pick up the fix; there are no per-procedure copies.
Verification
$ bunx biome check packages/host-service/src/trpc/router/terminal/terminal.ts
Checked 1 file in 12ms. No fixes applied.
$ cd packages/host-service && bun run typecheck
$ tsc --noEmit --emitDeclarationOnly false
typecheck exit=0
No existing tests cover this helper (grep -rl "toTerminalIoError" **/*.test.ts → no matches), so no test run applies.
Refs HOST-SERVICE-1N
https://claude.ai/code/session_0c69890b-c39f-420c-b03a-8038231a89ad
Summary by cubic
Classifies "Workspace worktree no longer exists..." terminal errors as NOT_FOUND in host-service instead of INTERNAL_SERVER_ERROR, addressing HOST-SERVICE-1N and stopping false 500s/Sentry alerts. Old: terminal.snapshot and send returned 500; New: they return 404 with cause { kind: "WORKTREE_GONE" }; message unchanged.
Review notes
- Change is isolated to
toTerminalIoError; both procedures inherit it; other errors keep their codes. - No tests updated; the helper had no coverage.
Migration
- Update any client logic that treated deleted worktree terminals as 500 to handle 404 NOT_FOUND instead.
- No action needed if you already treat missing/closed sessions as NOT_FOUND.
Summary by CodeRabbit
- Bug Fixes
- Improved error handling when a workspace worktree no longer exists.
- Users now receive a clear “not found” error with a specific worktree-related cause.