[BUG] Daemon endlessly respawns worker for a completed background session, blocking session resume (exit_with_message loop)

Status Open
Reported on v2.1.201
Maintainer reply None cached
Activity 0 comments · opened Aug 27, 2026

Environment

  • Claude Code v2.1.201, macOS (Darwin 25.5.0, Apple Silicon), Ghostty terminal
  • Long-running background daemon: claude daemon run --origin transient (PID had been alive for ~9 days, originally spawned by a session that had long since ended)

Summary

The background-agent daemon keeps a stale supervision entry for a completed background session (state "done" in ~/.claude/jobs/<id>/state.json) and endlessly respawns a worker for it. The zombie worker holds the session lock, so any attempt to resume that session (e.g. claude -c, which picks it as the most recent session) collides and dies with:

Sess<uuid> is currently running as a background agent (bg). Use `claude agents` to find and attach to it, or add --fork-session to branch off a copy.
[worker crashed (exit 1 — exit_with_message) — respawning…]

This repeats in a loop on every terminal/CLI restart.

Observations (all verified with ps/ppid)

  1. The affected bg job finished normally hours earlier (state: "done", result delivered).
  2. Killing the worker (--resume <session>.jsonl process) and its --bg-pty-host parent → daemon respawns both within seconds.
  3. Deleting ~/.claude/jobs/<id> entirely → daemon recreates the directory (skeleton with empty tmp/) and respawns the worker again.
  4. claude agents --json --all does not list the job anymore at this point — the daemon's in-memory supervision entry and the visible job list have diverged.
  5. ps -o pid,ppid confirms the respawned processes are children of the daemon PID.

Expected behavior

  • A job in state done should not keep a live worker holding the session lock, and should certainly not be respawned after its job directory is removed and it no longer appears in the agents list.
  • claude -c / --resume on a finished bg session should just resume it.

Workaround that resolved it

  1. Close all Claude sessions/windows.
  2. pkill -f "claude daemon"
  3. rm -rf ~/.claude/jobs/<id>
  4. Start Claude again (fresh daemon spawns automatically). Afterwards claude -c works normally.

Suspected cause

Stale in-memory supervision state in a long-lived transient daemon (9+ days uptime) that survives job completion and even job deletion; possibly a version-skew between the old daemon process and newer worker binaries (versions/2.1.201).

View original on GitHub ↗