Skip to content

fix: don't hang TUI when reattaching to a deleted session (#23344)#23355

Open
serenposh wants to merge 2 commits intoanomalyco:devfrom
serenposh:claude/vigorous-wiles-392f9a
Open

fix: don't hang TUI when reattaching to a deleted session (#23344)#23355
serenposh wants to merge 2 commits intoanomalyco:devfrom
serenposh:claude/vigorous-wiles-392f9a

Conversation

@serenposh
Copy link
Copy Markdown

@serenposh serenposh commented Apr 19, 2026

Issue for this PR

Closes #23344

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Running opencode -s <deleted-session-id> would hang the terminal — no ctrl+c, no ~., terminal had to be killed.

Cause: in routes/session/index.tsx, the effect that loads the session calls sdk.client.session.get({ sessionID }, { throwOnError: true }). For a deleted session the server returns 404, so the SDK throws before the existing if (!result.data) guard can run its "Session not found" toast + navigate({ type: "home" }) recovery path. The rejection surfaces inside an async createEffect, by which point the TUI has already entered raw-mode / alternate-screen — stdin is no longer reachable from the shell, so every keystroke is swallowed.

Fix: drop throwOnError and add an explicit .catch(() => undefined) so the existing recovery path actually runs. Also wrap the follow-up sync.session.sync(route.sessionID) in a try/catch (it also uses throwOnError: true internally) to cover the narrow race where the session is deleted between the two calls.

How did you verify your code works?

  • bun typecheck across all workspace packages (pre-push hook) — passes.
  • bun test --timeout 30000 in packages/opencode — 2002 pass / 11 skip / 1 todo / 0 fail.
  • Traced the repro: args.sessionIDroute.navigate({ type: "session", ... }) in app.tsxSession() mounts → the 404 from the get call is what killed the TUI before the guard could run. With the fix, the guard fires and you land on the home view with a "Session not found" toast.

Screenshots / recordings

N/A — behavior change, not a visual change. The user-visible surface is an existing toast that was already coded but unreachable.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

…yco#23344)

`opencode -s <deleted-id>` would render, the server 404 from `session.get`
would throw past the `!result.data` guard (since `throwOnError: true` was
set), surface as an unhandled rejection inside an async createEffect, and
leave the TUI half-mounted with stdin in raw mode — ctrl+c, ~. and every
other shortcut went unheard until the user killed the terminal.

Drop `throwOnError` + add an explicit `.catch` so the existing "Session
not found" toast + navigate-home path actually runs, and wrap the
follow-up `sync.session.sync` the same way for the race where the
session is deleted between the two calls.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@github-actions github-actions bot added the needs:compliance This means the issue will auto-close after 2 hours. label Apr 19, 2026
@github-actions github-actions bot removed the needs:compliance This means the issue will auto-close after 2 hours. label Apr 19, 2026
@github-actions
Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Reattaching to a deleted session makes opencode hard hang the terminal

2 participants