claude -p headless session hangs at startup when a version-directory lock is contended by a concurrent interactive claude session
Running a headless claude -p job (a scheduled macOS launchd task, no TTY) alongside a long-running interactive claude -c session on the same machine, both on the same installed CLI version.
Symptom: The headless claude -p invocation hangs indefinitely at startup (no output, no error, no timeout of its own — an external watchdog eventually SIGKILLs it after 480s). This happened on both an initial attempt and an immediate retry in the same run, both hanging the full duration.
Root cause, confirmed via --debug-file: Both hung attempts log this right before going silent:
[DEBUG] Cannot acquire lock for 2.1.259 - held by PID 1531
[ERROR] NON-FATAL: Lock acquisition failed for /Users/<user>/.local/share/claude/versions/2.1.259 (expected in multi-process scenarios): Lock already held by another process
PID 1531 was confirmed (via ps) to be the live, long-running interactive claude -c session on the same machine — not another instance of the headless job. Despite the log line being labeled NON-FATAL and expected in multi-process scenarios, the headless process does not recover from this — it logs a few more startup steps ([claudeai-mcp] Fetched 4 servers, writing ~/.claude.json atomically) and then produces zero further output for the rest of its lifetime, until externally killed.
Confirmed absent on a successful run the previous day: the identical job, same script, same version, run the day before with no interactive session active on that exact version, completed normally end-to-end (479 log lines, clean shutdown, Released PID lock for <version> logged at the end) with zero occurrences of the "Cannot acquire lock" message anywhere in its debug log.
Suspected trigger: both the interactive session and the headless job happened to be on the identical CLI version (2.1.259) at the same time, following a claude auto-update the same evening. In the days prior, the interactive session was on an older version (2.1.246 per its own debug log) while the headless job ran on a newer auto-updated version — no lock contention occurred during that whole window. The collision appears specifically when both processes are on the same version and one already holds whatever this per-version-directory lock protects.
Impact: for any setup running a scheduled/headless claude -p job alongside a persistent interactive session (a common pattern for background automation next to an assistant session), this causes an intermittent full hang with no automatic recovery — the job silently consumes its entire timeout budget instead of running in the ~1-2 minutes it normally takes, and recurs any time both processes land on the same version.
Workaround attempted: none found yet from the caller's side — this is a lock internal to the CLI's own startup sequence (version-directory single-instance guard), not something controllable via existing flags. --bare avoids one different known hang class (plugin loading) but breaks account-level MCP connector auth entirely, so it isn't usable here regardless.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗