Skip to content

terminal: stale tab on a pre-restart terminal id can't self-recover without a manual state re-fetch #991

@amrmelsayed

Description

@amrmelsayed

Background

Deferred from #971 (web terminal session-unknown fast-path).

After a Tower restart, persistent (shellper-backed) terminal sessions are reconnected under a new terminal id, and the old SQLite row is deleted. Both reconnect paths reassign the id:

  • startup reconcile: packages/codev/src/agent-farm/servers/tower-terminals.ts:646 (createSessionRaw → new id) and :669-672 (delete old row, save under new id)
  • on-the-fly reconnect: :832 and :868-872 (deleteTerminalSession(oldId) → new id)

Consequence: a browser (or VSCode) tab still holding the old id's WebSocket URL (/ws/terminal/<oldId>) will get a permanent close — 4404 for the web terminal after #971, or the HTTP 404 upgrade rejection for the VSCode terminal — and correctly gives up. But the old id is permanently dead, so a WS retry to the same URL can never recover it.

Recovery today relies on something re-fetching /api/state (which rehydrates and exposes the successor id) and the dashboard remounting the terminal onto the new wsPath (the Terminal effect is keyed on wsPath). That re-fetch is currently incidental (a user-driven refresh, a focus/poll event) rather than triggered by the give-up itself.

Work

On a permanent terminal close (the classifyUpgradeError(...) === 'permanent' branch added in #971), have the dashboard proactively re-fetch workspace state, resolve the session's successor id, and auto-remount the terminal onto the new wsPath — so a persistent session that came back under a new id self-heals without a manual refresh.

Notes

  • The same stale-id gap exists for the VSCode terminal (give-up + reconnect link, but no automatic successor-id remount). Worth considering the analogous affordance there; if folded in, this becomes area/cross-cutting.
  • This is a recovery/UX hardening, not a correctness bug — the 4404/404 give-up is already truthful (the old id really is gone).

Acceptance

  • After a Tower restart, an open dashboard terminal tab on a persistent session reconnects to its successor session automatically (no manual page refresh), within a small bounded delay.

Metadata

Metadata

Assignees

Labels

area/cross-cuttingTouches multiple areas — needs coordinated handling

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions