[BUG] `--verbose` changes `--output-format json` from a single object to a JSON array
Preflight Checklist
- [X] I have searched existing issues and this hasn't been reported yet
- [X] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
--output-format json is documented to return a single JSON object containing result, session_id, and metadata. When --verbose is also passed, it instead returns a JSON array of every session message, with the result object as the last element.
The same switch happens with no flag on the command line at all: --verbose is documented as overriding the viewMode setting, so setting "viewMode": "verbose" in ~/.claude/settings.json puts every --output-format json invocation into the array form permanently.
This means a display preference silently changes a machine-readable output contract. --verbose is documented as a display/logging control — cli-reference describes it as "Enable verbose logging, shows full turn-by-turn output. Overrides the viewMode setting for this session" — and --help describes it only as "Override verbose mode setting from config". Neither mentions any effect on --output-format json.
The consequence is that the documented jq examples on the headless page fail for any user with verbose view mode enabled, including this one from the docs:
session_id=$(claude -p "Start a review" --output-format json | jq -r '.session_id')
For a scripted/CI caller this is easy to miss, because the breakage is triggered by a setting made at some earlier time in a completely different context.
What Should Happen?
--output-format json should return the same single result object regardless of --verbose or viewMode, so that the machine-readable output contract is independent of display preferences.
If the array form is intentional, then --verbose, viewMode, and --output-format json should each document the interaction, and the jq examples on the headless page should be updated to work in both modes.
Error Messages/Logs
# Documented example, with --verbose — fails
$ claude -p "Reply with exactly: PING" --output-format json --setting-sources "" --verbose | jq -r '.result'
jq: error (at <stdin>:1): Cannot index array with string ("result")
# Same command without --verbose — works
$ claude -p "Reply with exactly: PING" --output-format json --setting-sources "" | jq -r '.result'
PING
Steps to Reproduce
- Run the documented command without
--verbose.--setting-sources ""is passed only to isolate the result from any local configuration:
``bash``
claude -p "Reply with exactly: PING" --output-format json --setting-sources ""
Top-level value is a JSON object. jq -r '.result' returns PING. This matches the documentation.
- Run the identical command with
--verbose:
``bash``
claude -p "Reply with exactly: PING" --output-format json --setting-sources "" --verbose
Top-level value is now a JSON array of 4 elements (system, rate_limit_event, assistant, result). jq -r '.result' fails with Cannot index array with string ("result"). The result object is at .[-1].
- To confirm the settings-driven path, remove
--verboseand--setting-sources "", and instead add to~/.claude/settings.json:
``json``
{ "viewMode": "verbose" }
Then run:
``bash``
claude -p "Reply with exactly: PING" --output-format json
The output is the array form again, with no flag on the command line.
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
Claude Code Version
2.1.220 (Claude Code)
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
Non-interactive/CI environment
Additional Information
The affected documentation is https://code.claude.com/docs/en/headless — the "Get structured output" section states "json: structured JSON with result, session ID, and metadata" and the tip block gives claude -p "Summarize this project" --output-format json | jq -r '.result'. The "Continue conversations" section gives the jq -r '.session_id' snippet quoted above.
Both were reproduced on macOS with Claude Code 2.1.220. The --setting-sources "" isolation means the behavior is reproducible on a clean machine with no local configuration.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗