Repository navigation
[Bug]: Cleanly exited Claude session is auto-resumed with claude --resume after an app restart (local macOS, hibernation off) #14228
Description
Operating system
macOS
Orca version
1.4.179 (arm64)
Details
Short summary: A Claude Code session that I ended deliberately — exit inside Claude, then exit in the shell, so both the agent and the terminal tab are gone — is auto-resumed with claude --resume <old-session-id> the next time I quit and reopen Orca. It comes back as if the session had crashed or been interrupted, even though I closed it cleanly. This is a purely local macOS workspace: no SSH target, no relay, no remote runtime, and experimental Agent Hibernation is off.
How can we reproduce it?
- macOS, local project (no SSH/remote runtime). Default TUI agent =
claude. Settings → experimental Agent Hibernation off. - Open a terminal tab in the project, run
claude, do some work in the session. - Type
exitinside Claude → back at the shell prompt, theclaudeprocess is gone. - Type
exitin the shell → the terminal tab closes on its own. - Quit Orca (⌘Q) and relaunch it.
- The project reopens with a terminal tab already running
claude --resume <the session id from step 2>.
Expected behavior
A session the user ended on purpose should not be a restore candidate. Closing Claude and its tab should retire the pane's agent record (prune it / write a close tombstone), so that only sessions that were still alive when Orca quit are resumed on relaunch. A discoverable setting for "restore agent sessions on launch" would help as a second-line fix (#12250, #13633), but the primary problem here is that a clean, user-initiated exit is treated as an unexpected termination.
What I can see in the persisted state
Profile store: ~/Library/Application Support/Orca/profiles/local-default/orca-data.json
-
workspaceSession.sleepingAgentSessionsByPaneKeyholds one record per pane:{ "paneKey": "<tabId>:<paneId>", "worktreeId": "<repoId>::/Users/…/<project>", "agent": "claude", "providerSession": { "key": "session_id", "id": "<uuid>", "transcriptPath": "/Users/…/.claude/projects/…/<uuid>.jsonl" }, "prompt": "<my last prompt, truncated>", "state": "working", "origin": "live", "capturedAt": 1786603058659, "updatedAt": 1786603041327 } -
workspaceSession.terminalSurfaceTombstonesByPaneKeyis{}on my install — it has never been populated, including for the panes I closed withexit. -
Records outlive their panes. In a rotated backup written at Aug 12 08:13 (
orca-data.json.bak.0…4), the only record still carriedstate: "working"withcapturedAtfrom Aug 11 18:00 — a session from the previous day. -
Across all six snapshots I have (5 backups + current), every record has
state: "working"andorigin: "live". I never see a record flip todoneor get removed. -
settings.experimentalAgentHibernationisfalse, so this restore is not coming from the hibernation feature path. -
sshTargets: [],sshRemotePtyLeases: []— nothing remote is involved.
Hypothesis (not verified — I only have the packaged app)
exit inside Claude does not produce a terminating status update, so the record's last known state stays "working" forever. #11598 documents the activation-time validation as discarding a record when state !== "done" && capturedAt - updatedAt > 30 min; in my record capturedAt - updatedAt is ~17 s, so a stale-but-working record passes validation and gets resumed. If that's right, the missing piece is retiring the record (or writing a tombstone) when the agent process exits normally / the pane is closed — not the staleness window.
Related, but not the same issue
- [Bug]: Windows restart auto-enters agent /resume state with no obvious toggle #12250 — Windows restart auto-enters
/resume, no discoverable toggle. Closest in symptom, but it's about an active session being restored plus the missing setting; here the session was cleanly exited, on macOS, locally. - [Feature] Auto-resume on project switch — any way to disable / is this already planned? #13633 — feature request for disabling auto-resume on project switch.
- [Bug]: Closed SSH terminal tabs resurrect: reattach re-creates persisted tabs, erases close tombstones, and auto-runs claude --resume on old sessions #12447 / [Bug]: open orca (ssh into VM dev box) always open 6-10 terminals & try to resume exited claude sessions #13679 / [Bug]: Remote-runtime host spawns a second tab running
claude --resume <id>for a session whose original pane is still alive (two live processes, one transcript) #13716 / [Bug]: Remote host restoring/spawning terminal tabs that were manually closed #9352 — same visible symptom (claude --resumeon old sessions, resurrected tabs), but all SSH/relay/remote-runtime paths. My setup has no SSH at all, so there is a local-only route to this. - [Bug]: Interrupted agent sessions are never auto-hibernated, and manual workspace sleep silently discards them on wake #11598 — sleep/wake record validation; source of the validation conditions quoted above.
Happy to pull more state or logs from my install if that helps narrow it.
Activity
erishforG commentedon Aug 14, 2026
I reproduced this on current main and traced it to resume authority surviving a confirmed agent exit. I opened #14534 with a focused fix.
A bare PTY exit intentionally preserves the sleeping-session record for crash recovery. However, Orca already emits an agent-exited fact only after foreground-process verification confirms that Claude has returned to the shell. The PR clears only that pane resume record at this confirmed transition, while preserving sibling panes and unexpected-PTY-loss recovery.
Regression coverage includes a confirmed agent exit followed immediately by PTY teardown, exact-pane isolation, and the existing crash-recovery behavior. I also manually verified the full macOS flow: exit Claude, exit the shell, restart Orca, and confirm that no Claude resume process is started.
erishforG commentedon Aug 14, 2026
The fix is ready in #14534 and has been verified with focused regression coverage plus a macOS exit-and-restart recording. It preserves unexpected PTY-loss recovery while retiring resume state only after a process-confirmed agent exit.
@AmethystLiang, when you have time, could you please take a look? Thank you.
erishforG commentedon Aug 17, 2026
@OrcaWin @AmethystLiang following up on PR #14534 — it conflicted with the pty-connection test file being split into ~50 focused files, so I moved the regression test into pty-connection-main-side-effect-authority.test.ts where it belongs, and rebased clean. CodeRabbit also caught that the ordering assertion only checked the first of two cleanup calls — fixed that too. This is P0 but the PR is labeled P1, flagging in case it's a triage gap.
shay2911 commentedon Aug 19, 2026
Confirmed on local macOS after updating to Orca 1.4.185, with Agent Hibernation not involved.
The persisted profile had 8 terminal tabs immediately before the update. The first post-update snapshot had 16. The updater trace shows the normal 1.4.185 quit/install/relaunch sequence; during renderer startup the daemon created 9 PTYs in the same second.
The pre-update session contained 8
sleepingAgentSessionsByPaneKeyrecords whose original tab IDs were absent fromtabsByWorktree(6 Claude, 2 OMP; allorigin: "live", stillworking/waiting). Relaunch converted those into 8 replacement agent tabs, plus one normal shell, explaining the exact 8 → 16 jump. Provider-session correlation confirmed that the replacement Claude tabs reused the orphan records' sessions rather than representing unrelated launches.After closing the resurrected tabs, the live profile still contained 8 orphan
working/liveresume records, so another restart could repeat the behavior. No profile values, prompts, tab titles, paths, or provider-session IDs are included here.This is strong independent confirmation of the mechanism described in this issue and of the need for #14534's process-confirmed exit cleanup.
LLLLLayer commentedon Aug 24, 2026
Still reproducing on 1.4.188 (arm64), local macOS, Agent Hibernation off, no SSH/remote runtime. #14534 is still open, so this is expected — but while digging into my own install I read the packaged renderer bundle, and two details contradict / extend the hypothesis in the original report. Both matter for whether the fix in #14534 is sufficient.
(Identifiers below are from the beautified
app.asarbundle of 1.4.188 — names may differ from source. No paths, prompts, tab titles, or provider-session IDs included.)1. The record is not merely left stale — it is actively rewritten back to
workingThe report's hypothesis is that "
exitinside Claude does not produce a terminating status update, so the record's last knownstatestaysworkingforever." That's not what the code does. InsetAgentStatus(out/renderer/assets/store-*.js), adonestatus for a resumable agent takes a dedicated branch that rewrites the recovery record asworking:So even when Orca does observe the
donetransition cleanly, the pane keeps astate: "working"/origin: "live"resume candidate. Theprompt: ""+lastAssistantMessage: undefinedshape is a reliable fingerprint for these in a profile dump — I have records in that exact shape sitting next to genuine mid-work captures.This looks intentional (keep the session identity so the pane can be resumed later), but it means "agent finished normally" and "agent was interrupted" are indistinguishable in the persisted record.
2. The staleness check is structurally dead for these records, not just narrowly missed
The original report notes its own record was "~17 s" and therefore passed. It's stronger than that: for every record produced by the live-recovery path above, the difference is exactly 0 by construction.
setAgentStatuscomputes oneupdatedAt, puts it onentry.updatedAt, and passes the same value ascapturedAt;sleepingRecordFromEntrythen copiesupdatedAt: args.entry.updatedAt. All records in my profile havecapturedAt === updatedAtto the millisecond.There is no comparison against now anywhere in this predicate, so age is irrelevant — I am carrying records captured 3–4 days ago that are still valid resume candidates today, unchanged across five rotated
orca-data.json.bak.*snapshots.3. A second trigger path: cold restore resumes in place, without the tab ever disappearing
The report describes pane/tab gone →
resumeSleepingAgentSessionsForWorktree→launchSleepingAgentSession→ new tab. There is a second route that produces no new tab, so it's easy to miss when counting tabs:If the pane and its split layout survive the restart but the PTY does not,
buildColdRestoreAgentResumeStartup()(out/renderer/assets/OnboardingInlineCommandTerminal-*.js) reads the same sleeping record and re-runsclaude --resume <session-id>into the original pane, then shows the "session restored" banner. My last restart hit exactly this: a session whose transcript had no new content for three days had its.jsonltouched 15 s after app start, in the sametabId:leafIdit originally ran in. Tab count never changed.Both routes read the same
sleepingAgentSessionsByPaneKeyentry, so a fix at the record level covers both — but repro steps that only check for extra tabs will miss this variant.Implication for #14534
Clearing the resume record on a process-confirmed agent exit is the right primary fix and would cover the reported repro. Two gaps look like they'd survive it, though:
working/liverecord that is a permanent resume candidate, because of (1).Date.now() - record.capturedAtagainst some window) as defense-in-depth would bound the blast radius of any missed exit signal, independent of exit detection.Separately, and consistent with #12250 / #13633: I went through
getDefaultSettings()in the main bundle, everyORCA_*variable referenced by the main-process bundle, and the Settings panes — there is no user-facing switch for this, and no internal escape hatch either. The only reachable kill switch is Settings → Agents → Agent status hooks, which works only as a side effect (no hooks → noproviderSession→sleepingRecordFromEntryreturnsnull→ no record), at the cost of all agent status, notifications, and auto-titles. Worth noting as evidence that the toggle asked for in #13633 has no workaround today.Happy to provide more structured detail from my profile if useful.
guo commentedon Aug 27, 2026
Still present on 1.4.188 (arm64), local macOS, Agent Hibernation off, no SSH/remote runtime.
Adding four things I did not find in the thread: how far the accumulation actually goes on a busy install, a severity multiplier nobody has raised, one property of the age bound @LLLLLayer proposed that I think justifies it as its own change rather than a follow-up to #14534, and a small correction.
(Counts and code only — no paths, project names, tab titles, prompts, or provider-session IDs.)
1. The accumulation is unbounded in practice, not only in theory
Snapshot of one install running a large parallel-agent fleet:
sleepingAgentSessionsByPaneKeyrecordsorca terminal list)capturedAt - updatedAtacross all 24 recordsAll 9 pass
isInvalidWorktreeActivationRecord. The guard reads 0.0 min on a record that is 9.8 days old, which is @LLLLLayer's point restated as a measurement: the predicate is not narrowly missing these, it is inert for them.Nothing retires them. They persist across restarts and accumulate per worktree, so the count tracks how many worktrees you have touched rather than converging.
2. Severity multiplier: a resurrected session inherits the yolo defaults
This is the part that I think changes the priority calculus, and I have not seen it raised.
YOLO_TUI_AGENT_ARGSin the main bundle mapsclaude(andclaude-agent-teams,openclaude,antigravity) to--dangerously-skip-permissions,codexto--dangerously-bypass-approvals-and-sandbox,geminito--yolo. Installs carryingsettings.agentYoloDefaultsMigratedhave those applied as their default args.So the failure mode is not only "an unexpected tab appears". It is: a session last touched 9 days ago relaunches unattended, with permission prompts bypassed, in a worktree whose branch, working tree and dependencies have all moved since that session last had context. Its first action after
--resumelands on a repo state it has never observed, without a prompt gate.3. The age bound is self-healing — it repairs existing installs, not just new ones
Worth spelling out, because it is an argument for shipping the bound independently rather than as a follow-up. When the predicate returns true the caller does not merely skip the launch:
It deletes the record. So an absolute bound (
Date.now() - record.capturedAt > window) garbage-collects every already-accumulated orphan at the next worktree activation: no migration, no user action, no profile editing — and specifically no app restart, which is the one remedy unavailable to anyone with a live fleet running.It also covers the class that exit detection structurally cannot. SIGKILL, force-quit, host reboot, or a status hook that simply does not fire all end the agent without emitting an exit transition to observe; you cannot detect an event that was never emitted. Only elapsed time bounds that class. #14534 and an age bound are complementary and touch different files.
Given the existing "an interrupted turn is still resumable" intent in that function, the window presumably wants to be generous — days, not hours. The asymmetry favours it: if the bound fires early the user loses only automatic resume, while the transcript and a manual
claude --resume <id>remain; the current behaviour launches agents unattended instead.4. Correction: there is an internal fence, but it is erased by the same rewrite
@LLLLLayer — re "no internal escape hatch either": there is one.
resumeSleepingAgentSessionsskips any record carryingautomaticResumeBlockedByunconditionally, before the validity check.It is not usable as a workaround, and the repo already says why, in
live-resume-anchor-record.ts:The fence is dropped by the same live-recovery rewrite that produces these records. Raising it because it confirms the conclusion (no user-reachable switch), and because a fence that an ordinary status update silently erases looks like a defect in its own right.
Happy to open a focused PR for the age bound in
isInvalidWorktreeActivationRecordwith coverage alongside the existingresume-sleeping-agent-session*.test.tsfiles, if a maintainer confirms that shape is wanted and what window is acceptable. Not opening one unprompted given #14534 is still awaiting review.guo commentedon Aug 28, 2026
A timestamped capture of this on 1.4.188 (arm64), local macOS, hibernation off — with a repro that needs no app restart, which I think widens the scope of #14534.
The original report resumes after ⌘Q + relaunch. Here the only actions were: close a tab, then activate that worktree. I instrumented for it because the evidence self-erases — the resurrected pane re-registers the session under its own paneKey, so the profile reads as self-consistent minutes later. A watcher snapshotted
orca-data.json+terminal listthe instant a newclaude --resumeprocess appeared.(Shapes, counts and timestamps only — no paths, project names, tab titles, prompts, or session ids.)
What the user did
Finished with an agent, closed its tab. The workspace still listed the agent in the sidebar afterwards. Clicking that workspace opened a tab resuming the closed session.
What was captured
Two snapshots, five minutes apart, around one session id:
launchAgent: nulllaunchAgentsleepingAgentSessionsByPaneKeyentry for the sessionstate: "working",origin: "live"Tab-level diff over the same window: one tab id removed (
launchAgent: null, the user's own), one tab id added (launchAgent: "claude"). Tab count is unchanged, so a repro that only counts tabs will miss this.Process table over the same window, distinguished by argument order — Orca prepends the yolo default from
settings.agentDefaultArgsand appends--resume, whereas a hand-started agent has the flags the other way round:So the record outlived the deliberate close, and the next activation appended a new agent tab for it. This is the
appends exactly one replacement tab for a husk panepath rather than the cold-restore-in-place variant, and it fires on plain tab-close + activate.Why the close does not retire the record
retireAgentPaneAuthoritydoes remove the record unless called withpreserveSleepingAgentSession, and the three call sites that pass it are legacy-worker rollback andretireSurface, not an ordinary close. Yet the record was still present at launch time, five minutes after the close. That points at the record being re-created after the close by the live-recovery writer — consistent with @LLLLLayer's finding that adonestatus for a resumable agent is rewritten back tostate: "working". I could not observe the exact moment of re-creation, so I am flagging that as the likely path rather than asserting it.Wider install picture
19–21 concurrent
claude --resumeprocesses, 16 of them carrying Orca's argument order. Two session ids each had two concurrent Orca-started processes, up 2+ days. Four panes were sitting on Claude'sResume from summary / Resume full session as-ispicker doing nothing — three of them in tabs withlaunchAgent: null, i.e. the in-place variant, one in an Orca-created tab.Interaction with a second defect
The replacement tab runs with cwd = the worktree root, but this session's transcript belongs to a different directory than that worktree, so the resumed process cannot find the session and lands on the picker. Filed separately as #16960 — the resume record binds a session to the pane's worktree rather than the agent's cwd. Where both apply, the resurrected pane is not merely unwanted, it is inert: it occupies a pane, shows as an agent in the sidebar, and can never reconcile with the session it names.
max-winderbaum commentedon Sep 2, 2026
Still reproducing on 1.4.184 (Linux x64), local profile,
experimentalAgentHibernation: false, no SSH/remote runtime. Adding a variant that I think is the simplest and most damaging form of this bug: the original process never exits. An idle Claude Code session that is still alive in its pane gets a secondclaude --resume <id>launched beside it on an ordinary worktree switch. No app restart, no tab close, no sidebar click.What happened
One long-running Claude Code session (a coordinator agent that stays open all day) in a single worktree. Over four hours Orca launched three duplicates of it:
session-created(UTC)…The-Merging@@9ba7c412clientId 7480cc1c) at 14:16:04…The-Merging@@3d4d2225…The-Merging@@2c70b234Each landed in a fresh "Terminal N" tab whose scrollback begins with Orca's own quoting:
Ancestry:
orca-ide daemon-entry.js → bash --rcfile ~/.config/orca/shell-ready/bash/rcfile → claude --resume. The original process (pid 1466611, started 11:26 UTC, same session id) was alive and idle the whole time. Both processes then append to the same.jsonl; the transcript now has 450parentUuidbranch points.Each launch coincided with me switching worktrees in the sidebar and coming back. The renderer killed the first two within 25–50 s once the original pane reattached, which is why the evidence self-erases (same observation as @guo's 2026-08-28 comment).
Why the guard passes
Read from the packaged bundle (1.4.184,
store-*.jsandworktree-activation-*.js):Every live Claude session gets a resume record, even while it is running. The agent-status reducer builds
liveRecoveryRecordviasleepingRecordFromEntry(..., origin: "live")on every hook update, and when the agent reportsdoneit keeps the record withstaterewritten to"working"andprompt: ""as long asgetAgentResumeArgvreturns non-null (retainsResumableRecoveryIdentity). So an idle-but-alive session always has a standing record. Hibernation is not involved.activateAndRevealWorktreecallsresumeSleepingAgentSessionsForWorktree(worktreeId)unconditionally, on every sidebar click / Cmd+J selection / return from another worktree.The only liveness check is renderer view state.
recordPaneIsOwnedByPreservedPanedecides ownership fromterminalLayoutsByTabId,ptyIdsByTabId, andtab.ptyId. It never asks the daemon whether the PTY is alive, and it never consultsisProviderAgentSessionOwnerLive, which already exists in main. WithterminalHiddenViewParking: true(the default), leaving the worktree parks the pane after 30 s; once the layout/PTY maps are dropped the record looks orphaned andlaunchSleepingAgentSessionruns.activeOrQueuedResumeClaimsProviderSessioncannot save it for the same reason Cold restore forks a second localclaude --resumeacross worktrees onto a live transcript #17807 describes: it only seesagentStatusByPaneKeyentries for tabs instate.tabsByWorktree[record.worktreeId], and the parked pane's status entry is exactly what was evicted.Why this is worse than a stray tab
Claude Code restores session-only scheduled jobs (
CronCreate) when it resumes a transcript. Each duplicate therefore fired the original session's hourly job within one second of launch, with full tool access, while the original was still running the same job. Two copies of an agent with write access to the same repo, beads, and staging environment. Fork #3 was caught only because it had been told to check for peers before acting.Fix shape
#14534 (retire on confirmed exit) and #16845 (age bound) do not cover this: the original never exited and the record is fresh. The wake sweep needs a real liveness check before launching: if any PTY on this machine currently runs a process for that
providerSession, focus it or skip, never launch. The daemon already answerslistSessionswithisAlive, and main already hasisProviderAgentSessionOwnerLive; the renderer sweep just does not call either.Workaround for anyone else hitting this: run the long-lived agent in tmux instead of an Orca tab, or launch it with
env -u ORCA_PANE_KEY claude …soclaude-hook.shexits early and Orca never learns the session id.daniel-rudaev commentedon Sep 8, 2026
On 1.4.197, with a paired desktop + a remote runtime (a Linux box) running the agent, activating a worktree that already holds a live
claudesession re-launchesclaude --resume <same session id>as a second tab in the same worktree. Over 35 hours across 26 worktrees we logged 136 occurrences, and it recurred after we switched Agent hibernation off, so this isn't gated by that setting.Evidence
Daemon log shows a
session-createdentry followed by a startup-command-delivery entry withviaShellArgs: falseandqueuedByShellReadyBarrier: true.commandLengthis either 56 (claude '--resume' '<uuid>') or 83 (same plus'--permission-mode' 'auto'), matching the composed launch command exactly. The desktop then closes the twin itself (session-tabs.close,reason: user). We confirmed directly, via the local agent-status file, one Claude session id present on two panes at once — the original and the duplicate.Mechanism (read from the shipped renderer bundle)
The desktop keeps a live "recovery record" for every running agent, refreshed periodically and independent of the hibernation setting. On worktree activation, it resumes any such record unless the pane can be verified alive. For a remote-runtime tab, that liveness check depends on a local map from tab id to pty id, which is populated only from a session-tabs snapshot's mirrored pty ids — and is deleted whenever that list comes back empty. When the map is empty for a live remote tab, the record reads as unverifiable and the desktop issues a fresh
createTabwith the resume command. The runtime's terminal-creation entry point (createMobileSessionTerminal) accepts that command verbatim, and because the daemon keys sessions on a tab-suffixed id, it has no way to recognize this as a duplicate of an already-attached session and simply creates a second one.Suggested fix
Key the resume claim on (worktree, agent, provider session id) at the runtime layer, and attach to the existing terminal instead of creating a new one whenever a live terminal already holds that session. Separately, treat an unhydrated/empty pty-id mirror as "unverifiable," not "dead" — it should block a resume rather than trigger one.
Related
We're running several shipped fixes in this area already (#11259, #11448, #12574, #13326, #16308, all present in 1.4.197) and the bug still reproduces, so whatever guard those added is incomplete for this remote-runtime path. We also noticed a change to the automatic-resume path on
maintoday (#19544) that may bear on this — happy to test against the first release that includes it, or to share more detail (logs, timestamps, reproduction steps) if useful.keefar commentedon Sep 9, 2026
This still happens on Mac OS. So annoying, and always resuming finished 65% ctx fable session is expensive.
wowpotato commentedon Sep 21, 2026
Opened #21317 for one specific path in this, and wanted to lay out how it sits against the other work here so nobody duplicates it.
What it fixes. When the agent exits and the pane returns to its shell, the pane's sleeping-session record is now marked
agentExited. Cold restore and the activation sweep both refuse to relaunch from a marked record, so reopening the workspace leaves you at a terminal instead ofclaude --resume <old id>. The record is flagged rather than deleted: the evidence is a foreground-process read, which can name a shell while the agent is merely suspended (Ctrl-Z), so a misread costs one automatic resume instead of the ability to recover the session at all.How it relates to the other PRs here — they are orthogonal, not competing:
session.onAgentExited, theagent-exitedfact path. I checked rather than assumed: applying its source patch to currentmainand running my regression test, the test still fails, because a foreground-confirmed shell return never reachesonAgentExited. Both handlers need the cleanup.claude --resume) by another client on workspace selection #21235 (a tab closed on one paired client resumed by another) is not covered by fix(agent-resume): drop a pane's resume anchor when its agent exits to the shell #21317: the flag comes from a foreground read on the pane that ran the agent, and the second client never observed one.Meanwhile, if the accumulation is bothering you, the records are plain JSON and safe to prune by hand. Quit Orca completely first — it rewrites this file on exit — then in
~/Library/Application Support/orca/profiles/local-default/orca-data.json, drop thestate: "done"entries underworkspaceSession.sleepingAgentSessionsByPaneKey(keepworkingones, and back the file up first). That stops the resurrections until a real fix lands; it does not prevent new records from accumulating.nwparker commentedon Oct 24, 2026
Thanks for the report! The clean-exit autoresume path has had fixes (#21714, v1.4.206, clears stale agent identity after shell exit). Please retest on 1.4.239+: exit Claude, exit the shell, quit and reopen Orca. If it still resumes, share: Orca version, OS, Claude Code version, whether you use a remote/paired client or only local, and the entry for that pane from
orca terminal list --jsonbefore quitting (redacted). Please redact anything private before sharing; screenshots or log excerpts are fine.syunki4649 commentedon Oct 26, 2026
Retested on Orca 1.4.241 (Windows 10 desktop app, SSH host = WSL2 Debian; Claude Code 2.1.310). Still reproduces for records left over from before the update.
Setup before the update: 1.4.222, a long-lived detached relay on the SSH host held ~19 PTYs. Several tabs in one workspace pointed at PTYs from relays that had already died earlier.
What happened after updating to 1.4.241:
orca terminal close --terminal <handle>on each stale tab did not remove the tabs. Instead, new PTYs were spawned under the new managed server and six previously-exited Claude sessions were started withclaude --resume <id>in that workspace./exit) was auto-resumed the same way.claude --resume <id>(the "activate the workspace" variant described above).All of the resumed sessions had
sleepingAgentSessionsByPaneKeyrecords captured at the moment of the update. #21714 keeps sleeping identity for remote panes, so my guess is that records written while these were SSH-relay panes were never retired.What looks fixed: on a fresh worktree on the new managed server, I started Claude, exchanged one message, and ran
/exit. Afterwards there was nosleepingAgentSessionsByPaneKeyrecord for that pane inprofile-state.db.orca terminal close --worktree <sel> --allthen closed both terminals and the tabs without triggering any resume.Remaining gaps:
--allis the only path I found that retires resume records).nativeChatResumeWorkOnRestartandexperimentalAgentHibernation, and neither covers terminal agents. A toggle like the ones requested in [Bug]: Windows restart auto-enters agent /resume state with no obvious toggle #12250 / [Feature] Auto-resume on project switch — any way to disable / is this already planned? #13633 would help.Possibly separate:
orca terminal createfails withNo PTY provider for connection "<ssh-id>": the SSH relay for this host is not attachedwhile the host shows as connected (also after Disconnect/Connect). Adding--environment <saved server>works, and the tab appears in the UI.orca terminal close --worktree <sel> --allreported "At least one PTY was not confirmed stopped: no registered provider can observe its host" and only stopped PTYs on the old relay.