Skip to content

Closing a terminal tab with a missing persisted session record resurrects the tab — close aborts on tab_not_found before PTY kill and snapshot prune #12920

Closed as duplicate

Description

@tozes

Summary

A terminal tab in the desync state described in #10747 (present in runtime hot state, no persisted workspace-session record) is not only unclosable from the CLI — it visibly resurrects after every close attempt in the UI. The tab disappears for a moment (optimistic client removal), the close RPC fails with tab_not_found, the runtime republishes the unchanged hot-state snapshot, and the tab reappears. The failure is deterministic, so the tab is immortal until its PTY dies or the runtime restarts.

This report adds two things to #10747:

  1. The user-facing resurrection loop, with a trace-log timeline of one tab "closed" six times over three hours.
  2. Evidence that the desync can also arise from a partially completed close (persisted record removed, then a later step failed), not only from a failed reveal at creation time.

Observed behavior

Environment: Linux desktop client, Orca 1.4.x, local runtime plus SSH worktrees.

  • Closing an affected tab in the UI: the tab closes for a moment, then returns within seconds.

  • ~/.config/orca/logs/main.trace.ndjson for one session (2026-08-06): 14 runtime.session-tabs.close spans across three bursts (11:26, 14:18, 14:22) all ended in failure. One tab id appears six times — the user kept re-closing the same resurrected tab. 40 other closes in the same window recorded decision: allowed and stuck.

  • Every failing span carries the same exit:

    Error: tab_not_found
        at OrcaRuntimeService.removePersistedHeadlessTerminalTab (.../out/main/index.js)
        at OrcaRuntimeService.closeHeadlessMobileTerminalTab (.../out/main/index.js)
        at OrcaRuntimeService.closeMobileSessionTab (.../out/main/index.js)
    
  • Handle-based terminal.close RPCs against the same tabs also fail with tab_not_found, but they kill the daemon PTY session before the handler throws (daemon log shows session-killed / session-exited in lockstep with the failing RPCs). The terminals then stay gone — close "works" by side effect while reporting an error. This is the only non-restart escape from the loop.

Root cause

Same throw site as #10747, but the ordering inside closeHeadlessMobileTerminalTab is what turns it into a resurrection loop (src/main/runtime/orca-runtime.ts @ f713739, lines ~8049-8108):

  1. removePersistedHeadlessTerminalTab(worktreeId, closedParentTabId, { allowMissing: options.allowMissingPersistedTab }) — throws tab_not_found when the persisted row is missing (line ~8057). Only one internal recovery caller passes allowMissingPersistedTab: true.
  2. PTY kill (line ~8084) — never reached.
  3. Hot-state snapshot prune + republish (line ~8088) — never reached.

So the close aborts with the PTY alive and the hot snapshot untouched. The client already removed the tab optimistically; the next snapshot publication re-adds it.

By the time closeHeadlessMobileTerminalTab runs, closeMobileSessionTab has already resolved the tab from the hot snapshot — the tab provably exists in hot state. A missing persisted row at that point can only mean the persisted and hot states have diverged, and refusing the close can never repair that divergence; it just makes the tab immortal.

How the desync arises

Two origins observed/inferred:

Suggested fix

Make the headless close idempotent: treat a missing persisted row as "already de-persisted" and continue with the PTY kill and hot-state prune (i.e., what allowMissingPersistedTab: true already does for the relay-recovery caller, applied unconditionally). This fixes both this resurrection loop and #10747's unclosable CLI tabs, and makes the partial-close origin self-healing: the second close attempt completes the interrupted transaction instead of failing forever.

PR to follow.

Activity

  1. AmethystLiang commented on Aug 6, 2026

    @AmethystLiang
    Contributor

    thanks for reporting. looking into it

  2. added a commit that references this issue on Aug 10, 2026
    e29b0be
  3. waymakerlabs commented on Aug 12, 2026

    @waymakerlabs

    I can reproduce a closely related resurrection on macOS (M4 Pro Mac mini, Orca v1.4.180, local runtime).

    Reproduction:

    1. orca status --json reported a ready/reachable runtime (app PID and runtime ID stayed the same).
    2. Baseline orca terminal list --json showed 9 terminals.
    3. After closing the tab(s) under test, the immediate list showed 3 terminals.
    4. I switched to another project and returned to the original project.
    5. The list then showed 7 terminals again.

    The returned entries were not the same terminal records: they had new handle, ptyId, tabId, and incarnationId values, while reporting connected: true and orphaned: false.

    Several returned tabs launched Claude with --resume using the same provider session IDs as the pre-close tabs, including:

    • legacy-lens hr 773회 실행 이어가기
    • legacy-lens API 게이트웨이 응답 한도 재현 검증
    • setup-legacy-lens-live-publishing
    • Legacy-lens 계획 1단계 실행

    A process-tree check also showed fresh chains of:

    /usr/bin/login -flpq -> /bin/zsh -l -> claude --dangerously-skip-permissions --resume <session-id>
    

    So this is not only a stale rendered tab: returning to the worktree creates new PTYs/Claude processes and resumes the old provider sessions.

    Expected: closing a tab removes it from persisted workspace state and terminates its PTY; returning to the worktree must not restore it.

    Actual: the tab disappears after close, but switching worktrees causes Orca to hydrate the old session and create a new terminal tab.

    This appears closely related to #12920/#12922, reproduced here on macOS. The /usr/bin/login -flpq chain may also be related to #13764, but the user-visible failure is persisted tab/session resurrection.

  4. waymakerlabs commented on Aug 12, 2026

    @waymakerlabs

    Additional observation from the same macOS v1.4.180 reproduction: the result depends on how the tab is closed.

    • If I type exit in the terminal to terminate the shell/Claude process, the tab appears closed in the current project.
    • After switching to another project and returning, Orca creates a new terminal/PTY for that tab and starts Claude with --resume for the same provider session.
    • If I close the tab with the UI X button, I have not been able to reproduce the resurrection; it remains closed after switching projects.

    This suggests that the process-exit/agent-exit path is not recording the same durable close state as the explicit UI-close path. The old provider-session reference remains eligible for restoration, and project/worktree switching then rehydrates it.

    Could you check whether the exit path should mark the tab/session as permanently closed (or remove it from persisted workspace state) instead of making it resumable on the next project switch?

  5. tozes commented on Aug 17, 2026

    @tozes
    ContributorAuthor

    Fresh reproduction on Linux with Orca 1.4.184. This is still present and now also affects the supervised-worker cleanup path.

    At 2026-08-17 12:42 UTC, Orca tried to release two completed worker terminals in the same worktree (/home/tozes/dev/orca):

    • term_41bcfa18-d16c-4100-ab57-059927f8792b / PTY ...@@04489215
    • term_666f921c-af53-49f7-a999-8bb80769b62e / PTY ...@@12c7a52a

    For both terminals, orca orchestration worker-release returned:

    state: release_unknown
    lastError: tab_not_found
    recovery: inspect worker-show, then repeat worker-release with the same retry request
    

    I followed that recovery exactly. worker-show proved both Dispatches were completed and both exact PTYs had exited. Replaying worker-release with each original request ID returned the same tab_not_found result.

    The daemon log confirms that the close attempts killed both PTYs before the RPC failed:

    2026-08-17T12:42:11.639Z session-killed ...@@04489215
    2026-08-17T12:42:11.841Z session-exited ...@@04489215 code=1
    2026-08-17T12:42:12.002Z session-killed ...@@12c7a52a
    2026-08-17T12:42:12.020Z session-exited ...@@12c7a52a code=1
    

    Afterward, orca terminal list --worktree <exact-worktree-id> --include-visual-layouts --json returned 0 terminals, while the user-facing terminal/tab remains stubborn and refuses to close. This is a concrete split-brain state: the PTY is gone and the runtime terminal list is empty, but tab cleanup still looks up a missing persisted record and reports tab_not_found.

    This matches the handle-close variant in the original report: the side effect succeeds, but the close operation still fails because persisted tab removal is not idempotent. It also shows that the issue affects current lifecycle cleanup, not only manual UI close.

    PR #12922 already implements the idempotent close behavior and has no CodeRabbit findings. Please approve its pending fork-PR workflow run and review it; this current reproduction blocks reliable worker cleanup and leaves uncloseable terminal UI behind.

  6. nwparker commented on Aug 23, 2026

    @nwparker
    Contributor

    Closing as a duplicate of #10747.
    Disagree? Please respond! I will re-visit this ticket in 5 days. If you respond, I will re-open it 🙏.

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

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions