Skip to content

"Resume background agent" launches claude --session-id <new> instead of attaching to the live bg agent, surfacing an empty/ghost session #6622

Description

@danmirman

Summary

When resuming a backgrounded Claude agent (a panel titled "resume-background-agent"), cmux launches:

claude --session-id <fresh-uuid> --settings {…cmux hooks…} --dangerously-skip-permissions

i.e. it mints a brand-new session id and starts an empty session, instead of attaching to / --resume-ing the agent's existing session. The user's real conversation is still alive as a different background-agent session in the Claude Code daemon. The freshly-minted id never receives a message, so Claude Code never writes a transcript for it — it becomes an unrecoverable "ghost" id.

Environment

  • cmux: 0.64.16
  • OS: macOS, Apple Silicon
  • Claude Code: 2.1.177

Symptoms (user-visible)

  • The panel shows an empty / very-early conversation ("most of my conversation is gone").
  • Restarting cmux re-runs the same --session-id <ghost> command → the empty session reappears every time, and the panel is eventually dropped from live state entirely.
  • claude --resume <ghost-id> in any terminal → No conversation found with session ID: <ghost-id> (correct — nothing was ever written there).
  • The actual conversation is a separate live background agent under a different id; resuming that id gives Session … is currently running as a background agent (bg).

Evidence — from cmux's own persisted state

~/Library/Application Support/cmux/session-com.cmuxterm.app-previous.json, the affected panel object:

{
  "kind": "claude",
  "sessionId": "<ghost-uuid>",
  "workingDirectory": "~/Projects/<repo>",
  "launchCommand": {
    "arguments": ["…/claude", "--session-id", "<ghost-uuid>", "--settings", "", "--dangerously-skip-permissions"]
  }
}

Note the launch uses --session-id (create-new) with no --resume and no --fork-session. Other, working panels in the same window correctly used --resume <existing-id>.

The corresponding real agent, from claude agents --json:

{"id":"<real-id>","kind":"background","name":"resume-background-agent","status":"idle","state":"blocked"}

So the panel's tracked sessionId (<ghost-uuid>) does not match the live agent's real session id (<real-id>).

Expected

"Resume background agent" should attach to the existing background session, reusing the agent's real session id — e.g. the claude agents attach path, or claude --resume <existing-id> (optionally --fork-session if a divergent branch is intended). It should never mint a new empty --session-id. The panel's tracked sessionId should be the agent's actual session id, so that a later resume — in cmux or a plain terminal — lands on the real conversation.

Impact

The user is shown an empty session in place of their real conversation, and the mismatch persists across restarts, making it appear the conversation was permanently lost. (It wasn't — it was a live background agent under a different id — but cmux surfaced the wrong, empty id, with no way back to the right one from the UI.)

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