Skip to content

[Bug]: defaultTerminalTabsAppliedByWorktreeId is never persisted — every launch and re-attach spawns a fresh default terminal in every workspace #18117

Closed

Description

@leedia-tech

Summary

workspaceSession.defaultTerminalTabsAppliedByWorktreeId is never persisted. It stays {}
forever, so on every launch — and on every pane re-attach during normal use — Orca treats every
worktree as "default terminal tabs have never been applied" and spawns a fresh
pendingActivationSpawn terminal into it. The previously attached agent tab is dropped from the
tab list, so from the user's side the workspace looks empty, or shows a second, blank
Terminal N next to the real one.

Seen on a headless Linux host running orca serve (no GUI client on the same machine), but the
persistence failure itself looks platform-independent.

Environment

  • Orca 1.4.195 (auto-updated from 1.4.188), Electron 43.4.1
  • Debian 13, headless: orca serve --port … --pairing-address … --mobile-pairing --json
  • 88 known worktrees, ~14 with a live agent
  • experimentalAgentHibernation: false

Evidence that the map is never written

After ~3 h of uptime, with dozens of workspaces opened in that time:

defaultTerminalTabsAppliedByWorktreeId     0        <-- empty
tabsByWorktree                             45
unifiedTabs                                45
tabGroups                                  45
activeTabIdByWorktree                      45
activeTabTypeByWorktree                    14
lastVisitedAtByWorktreeId                  2

All the sibling maps use the same <repoId>::<path> key shape and persist fine, so this is
not a key-validation drop in the session schema.

In the updater's own pre-upgrade backup (orca-data.json.bak-…-pre-1.4.195) the field is
absent entirely; the 1.4.195 migration creates it empty. It has never held a single entry since.

Code path

Minified 1.4.195 app.asar:

function to(e, t, n, r, a, o, s, c) {
  if (!o || e.defaultTerminalTabsAppliedByWorktreeId[t] || (e.markDefaultTerminalTabsApplied(t), o.tabs.length === 0)) return null;
  …
  e.createTab(t, undefined, undefined, { pendingActivationSpawn: true, recordInteraction: false, … })
}

The guard is the map lookup. With the map permanently empty the guard never fires, so the
createTab below it runs every single time.

Observed behaviour

1 — At launch. Right after the 1.4.195 auto-update restart, every workspace that had tabs got
a fresh Terminal N with pendingActivationSpawn: true and no launchAgent, replacing the tab
that had been bound to a running agent. Before/after for one workspace:

before  { id: 4bacc20d…, ptyId: …@@25da8b2a, title: "Terminal 1",
          launchAgent: "claude",
          aiVaultTitle: { agent: "claude", sessionId: "d80d09a9…", title: "…" } }

after   { id: 2fd4d453…, ptyId: …@@bc963996, title: "Terminal 2",
          startupCwd: "…", pendingActivationSpawn: true }        // no launchAgent, no aiVaultTitle

unifiedTabs and tabGroups for that worktree went from 1 entry to 0 across the same restart.

2 — During normal use, not only at launch. daemon.log for a single worktree, one session
(local time), while the app had been up for two hours:

09:28:13  session-created  <wt>@@43a28b1d
09:28:19  session-created  <wt>@@Wb0plBVl     <- second terminal, 6 s later
09:28:21  session-killed   <wt>@@43a28b1d
09:53:19  session-created  <wt>@@11a2b800     <- happens again on re-open
09:53:28  session-killed   <wt>@@Wb0plBVl

Workaround (verified)

With Orca stopped, pre-populate the map from the known worktrees:

ws = data["workspaceSession"]
ids = set(ws["tabsByWorktree"]) | set(data["worktreeMeta"])
ws["defaultTerminalTabsAppliedByWorktreeId"] = {i: True for i in ids}

After restarting: the map still held all 88 entries (so it is only the write path that is
broken, not the read/validate path), no default terminal was created in any existing
workspace, and the count settled at exactly one terminal per workspace. Since the app still
never writes the map itself, this has to be re-applied whenever the app is stopped, otherwise
newly created workspaces drift back into the same state.

Expected

Either markDefaultTerminalTabsApplied actually persists, or the restore path should not treat a
workspace that already has tabs in tabsByWorktree as needing default tabs applied.

Possibly related

Activity

  1. innocarpe commented on Sep 2, 2026

    @innocarpe
    Contributor

    Opened a focused fix: #18223

    defaultTerminalTabsAppliedByWorktreeId never left {} because persist snapshots that write tabs omitted this write-once map, and a later full session replace / hydration treated that omission as "never applied". The host PTY-binding persist now stamps the marker, and omitted snapshots union it instead of wiping it.

    After markDefaultTerminalTabsApplied(id), a persist/patch/hydration round-trip still has that worktreeId, so default tabs are not applied again.

  2. added a commit that references this issue on Sep 17, 2026
    281deb1
  3. added theissue type on Sep 19, 2026
  4. added a commit that references this issue on Sep 19, 2026
    2741bda
  5. madeat3am commented on Oct 3, 2026

    @madeat3am

    Another data point from 1.4.217 (macOS, Apple Silicon). Here it showed up as a single burst, not a slow accumulation.

    What happened

    • I activated a workspace from the sidebar (trace breadcrumb sidebar_worktree_activate, wasActive:false).
    • Within about 3 seconds, Orca spawned 105 blank Terminal N shells in that one workspace and wrote 210 tab records (105 distinct titles, each saved twice).
    • Trace: 105 × persistence.pty-binding with binding.origin: "spawn" and binding.misses: "tab_missing,layout_missing,incarnation,not_durable".
    • daemon.log: 105 × client-hello-accepted (clientId: "resolver-health-check"), each followed by a no-command session-created.
    • The burst stopped once the workspace's defaultTerminalTabsAppliedByWorktreeId entry was finally persisted, about 50 seconds later.
    • None of these came from the CLI. No terminal create or worktree create calls were made in that window.

    Why I think it's this issue

    • In the last orca-data.json snapshot before the move to profile-state.db, defaultTerminalTabsAppliedByWorktreeId had 66 entries, including this workspace.
    • In the live profile-state.db (workspaceSession document) it had 44. 151 known workspaces (from tabsByWorktree, unifiedTabs and worktreeMeta) have no entry.
    • So the map seems to have lost entries in that migration. Any unflagged workspace can then burst on first activation.

    Workaround I'm applying (Orca fully quit; back up profile-state.db first)

    • Set defaultTerminalTabsAppliedByWorktreeId[id] = true for every id in tabsByWorktree ∪ unifiedTabs ∪ worktreeMeta.
    • Recompute content_hash (SHA-256 of the payload).
    • Bump both the document revision and profile_state_meta.revision.

    Happy to share sanitized trace and daemon excerpts if useful.

  6. innocarpe commented on Oct 4, 2026

    @innocarpe
    Contributor

    Thanks for the detailed recurrence on Orca 1.4.217. A burst of 105 no-command shells in about three seconds, followed by missing map entries after the profile-state migration, needs a fresh investigation; the close under #21630 does not cover this reproduction. I am reopening #18117.

    Please keep the original profile-state.db and a backup unchanged if feasible. Do not apply the proposed map, revision, or content_hash edits to the only copy. The sanitized trace you offered would help; please pseudonymize user and worktree IDs and remove local paths. I will not treat the direct database rewrite as a product fix until its migration assumptions are verified.

  7. innocarpe commented on Oct 4, 2026

    @innocarpe
    Contributor

    Correction to my previous comment: I cannot reopen #18117 from my contributor account; the issue remains closed, and I am asking a maintainer to reopen it for this reported recurrence. My wording that I was reopening it was inaccurate. The request to preserve a backup and share a sanitized trace still stands.

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

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions