Claude CLI v2.1.81 crashes with 'Unexpected' when invoked by macOS launchd

Resolved 💬 2 comments Opened Mar 23, 2026 by arunankuven Closed Mar 25, 2026

Description

Claude CLI v2.1.81 fails with error: An unknown error occurred (Unexpected) when invoked by macOS launchd (LaunchAgent). This is a regression — the same setup worked correctly with v2.1.78 through March 16, 2026.

Reproduction

  1. Create a LaunchAgent plist that runs claude -p "echo hello" --dangerously-skip-permissions < /dev/null
  2. Load it: launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/my-task.plist
  3. Trigger it: launchctl start my-task
  4. Observe: exit code 1, stderr: error: An unknown error occurred (Unexpected)

The same command works perfectly when run from an interactive terminal or via env -i.

Environment

  • macOS Darwin 25.2.0 (Apple Silicon)
  • Claude Code v2.1.81 (~/.local/share/claude/versions/2.1.81, updated Mar 21)
  • Previous working version: ~v2.1.78 (last successful launchd run: Mar 16)

What I've ruled out

  • File descriptors: ulimit -n is 2147483646 inside the wrapper, confirmed via echo. Not the issue despite the error message sometimes mentioning it.
  • HOME/USER env vars: Set explicitly in wrapper script. Confirmed with echo $HOME inside launchd.
  • PATH: Claude binary found at correct path, confirmed with which claude.
  • Keychain access: Tried security unlock-keychain — no effect.
  • Pseudo-TTY: Tried wrapping with script -q — same error.
  • stdin: Redirected from /dev/null — no effect.

Key evidence

  • claude -p "say: test" --dangerously-skip-permissions < /dev/null → works from terminal, fails from launchd
  • The wrapper script itself executes (confirmed with echo and file writes before the claude call)
  • The Claude binary at v2.1.81 was installed Mar 21; failures started Mar 20 (likely auto-updated during that window)
  • Older versions (~2.1.78) worked with the identical launchd setup

Expected behavior

claude -p should work when invoked by launchd, as it did in previous versions. This is the documented pattern for scheduling Claude Code tasks.

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗