claude -p hangs forever at startup under launchd when logged in (zero output, all threads parked) — scheduled automation silently broken since daemon-service shutdown (~2.1.19x)

Open 💬 0 comments Opened Jul 6, 2026 by ban5104

Summary

Since ~2026-07-01, claude -p "<prompt>" hangs forever at startup (zero output, ~0.3s CPU then parked indefinitely) whenever the process ancestor is launchd (LaunchAgent) and the CLI is logged in. The same command works from any session-descended shell. This silently broke every scheduled automation on this Mac (three separate launchd jobs driving claude -p).

Likely related to #69864 (claude --print fails with 401 when no interactive session is open, regression in 2.1.185) — same era, same scheduled-use breakage, but the failure mode here is an eternal hang, not a 401.

Environment

  • Claude Code 2.1.201 (also reproduced on 2.1.197, 2.1.199 — pinning versions does not help)
  • macOS Tahoe 26.5.1 (Darwin 25.5.0), Apple Silicon, Mac mini
  • Pro/Max subscription (OAuth), credentials in login Keychain (no ANTHROPIC_API_KEY)
  • Install: native binary at ~/.local/share/claude/versions/<v>

Reproduction

  1. LaunchAgent plist running a script whose payload is:

``sh
export PATH="/opt/homebrew/bin:$HOME/.local/bin:/usr/bin:/bin"
claude -p "Reply OK" --model haiku > /tmp/out.log 2>&1
``

  1. launchctl kickstart gui/$UID/<label>
  2. Process starts, accumulates ~0.3s CPU, then parks forever: zero bytes of stdout/stderr (even with --debug), no session JSONL created under ~/.claude/projects/, no child processes ever forked.

Same script from an interactive shell (or any session-descended process, even with a launchd-identical bare env via env -i) completes normally in seconds.

Discriminating matrix (each row = a live launchd probe on this machine)

| Variant under launchd | Result |
|---|---|
| claude -p (logged in) | hangs forever |
| claude -p with fresh unauthenticated $HOME | fails fast + clean: "Not logged in · Please run /login", exit 1, ~1s |
| claude daemon status | works (exit 0, correct output) |
| claude -p + --strict-mcp-config --mcp-config '{"mcpServers":{}}' | hangs |
| + --settings '{"disableClaudeAiConnectors":true}' | hangs |
| + --settings '{"disableAllHooks":true}' | hangs |
| + --settings with every plugin disabled (enabledPlugins all false) | hangs |
| + --settings '{"apiKeyHelper":"<script echoing a dummy key>"}' | hangs |
| ANTHROPIC_API_KEY=<dummy> in env | hangs (no fast 401) |
| CLI pinned to 2.1.197 / 2.1.199 / 2.1.201 | hangs on all |
| plist SessionCreate=true | hangs |
| wrapped in osascript -e 'do shell script …' | hangs |
| stale ~/.claude/daemon/roster.json + daemon-auth-status.json cleared | hangs |
| healthy daemon running (claude daemon run, control.sock: reachable) | hangs |

Also checked: zero tccd activity during the hang (TCC never consulted), no NetworkExtension content filters, no system proxies, security find-generic-password for "Claude Code-credentials" works fine under launchd.

Forensics on a hung instance

  • sample: main thread in kevent64, "HTTP Client" thread in kevent64 (idle), 10 "Bun Pool" threads in __ulock_wait2 — everything parked, classic lost-wakeup/never-resolving-await shape.
  • lsof: 3 ESTABLISHED HTTPS connections to api.anthropic.com that never progress, and one AF_UNIX socketpair whose peer endpoint does not exist in any live process — the client appears to await a rendezvous/handshake with a peer that died (or was never created).
  • No children are ever forked (sampled pgrep -P at 150ms intervals from spawn).

Timeline / trigger

  • ~/.claude/daemon.log final line: [supervisor] shutting down (cause=signal, uptime=36351s, leases=0, live_workers=1) at 2026-07-01T04:05:50Z — the long-lived daemon service went away and never returned ("Service install is disabled in this version — the daemon runs on demand").
  • Last successful launchd claude -p on this machine: 2026-07-01T02:21Z. Every attempt after the daemon shutdown (+ a reboot on Jul 2 that wiped /tmp/cc-daemon-501/… sockets) hangs.
  • Interactive and session-descended usage continued to work throughout.

Impact

Any Pro/Max subscriber driving claude -p from launchd/cron for scheduled automation is silently broken: jobs hang forever (or until an external watchdog kills them), producing zero output and zero diagnostics. On this machine that was three independent daily/2-hourly pipelines. The hang variant is worse than #69864's 401 — nothing errors, so monitoring sees "still running".

Workaround

Spawn from a session-descended context instead of launchd — e.g. a SessionStart hook that backgrounds the job (works reliably), or manual shell runs. launchd jobs act as a canary: they will presumably start working again when this is fixed.

Ask

A fast, machine-readable failure (as suggested in #69864) would already help — but the hang itself looks like a lost-wakeup in the logged-in -p startup path when no session/daemon rendezvous is possible. Happy to run instrumented builds or provide more forensics.

🤖 Generated with Claude Code

View original on GitHub ↗