[BUG] `claude -p "/usage" --output-format json` intermittently fails right after a long print-mode run — exit 5, or `is_error:false` envelope with no `result`

Status Open
Maintainer reply None cached
Activity 1 comment · opened Aug 19, 2026

Environment

  • Claude Code v2.1.235
  • Linux (Debian container, ChromeOS Crostini)
  • Subscription auth (claude.ai login, not an API key)
  • Invoked non-interactively from a systemd user unit (bash, set -uo pipefail)
  • A Stop hook is configured in ~/.claude/settings.json — noting because of #38651, though that variant is consistent and this one is intermittent

What happens

claude -p "/usage" --output-format json intermittently fails, in two shapes, observed three times on 2026-08-19 between 12:19Z and 14:19Z:

  1. Exit code 5 (twice). Stdout produced nothing usable. Our script discarded stderr (2>/dev/null), so no error text was captured; the exit code was recovered from systemd after set -e killed the calling script: Main process exited, code=exited, status=5/NOTINSTALLED.
  2. Exit 0 with a success-shaped envelope missing its payload (once): is_error: false, num_turns: 0, and no .result key at all — jq -e '.result' fails on it.

The same command otherwise succeeds dozens of times a day in the same environment: it runs at the top of a 16-minute timer tick and has never needed more than one 15-second retry there.

The suspicious correlation

Both exit-5 failures happened seconds after a long print-mode run finished in the same working directory — a ~20–30 minute, ~100-turn claude -p call (an unattended build loop; the /usage read is its post-run bookkeeping). Failure rate immediately after such a call: 2 of 2. At any other time: ~0 across dozens of calls that day.

The date also coincides with status.claude.com incidents ("elevated errors", evening of Aug 18 and morning of Aug 19 UTC), so this may be a server-side error being wrapped rather than a client-side race — not distinguishable from outside.

Why it matters

The second variant is the worse one: a success-shaped envelope around a failure. Automation has to detect it by noticing a missing field on an is_error: false response. If the underlying request failed, the envelope should say is_error: true, and the exit code for failure should be consistent and documented (what does 5 mean?).

Related: #38623, #38706, #38805, #39053 (empty result string variants), #38651 (Stop-hook-triggered, consistent).

Repro

No deterministic repro found. The pattern that maximises the odds: finish a long (~100-turn) claude -p run, then immediately run claude -p "/usage" --output-format json in the same directory.

View original on GitHub ↗

This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗