claude -p "/code-review max" with a model override silently deadlocks on large branch diffs (model is forced onto all pipeline subagents; identical config works interactively)
Environment
- Claude Code 2.1.220, WSL2 Ubuntu 24, native installer (
~/.local/bin/claude) - Subscription: Max 20x (rate limit events show
status: allowedthroughout) - Repro'd both from a clean login shell (no parent CC session, hooks disabled) and from inside a session
Summary
In print mode, specifying a model — either via --model <m> or via --settings '{"model":"<m>"}' — forces every subagent spawned by the built-in /code-review pipeline onto that model. On a small diff (no subagent spawn) this works. On a real branch diff (41 files, +1260 lines), the pipeline's subagent orchestration silently deadlocks: after system:init, the stream-json emits zero further events, num_turns stays 0, the process never exits, and on SIGTERM it flushes result: "" — while modelUsage shows the model was consuming tokens (~$0.76 equivalent in the first 150s). No error is ever surfaced.
The identical model configuration (~/.claude/settings.json → "model": "claude-opus-4-8[1m]") runs /code-review max flawlessly in interactive mode on the same repo, same diff, same machine. The bug is headless-only.
Repro matrix (all on 2.1.220, --settings '{"disableAllHooks":true}' --strict-mcp-config --permission-mode bypassPermissions, stdin </dev/null)
| Scope | Model override | Result |
|---|---|---|
| large diff (41 files, +1260) | --model claude-opus-4-8[1m] | silent deadlock: init event only, 0 turns, never returns; empty result flushed on kill |
| large diff | --settings '{"model":"claude-opus-4-8[1m]"}' | same deadlock (240s probe: 0 task_started, modelUsage shows only the pinned model) |
| tiny diff (1 file) | --model claude-opus-4-8[1m] | completes in ~150s — but single-agent, no subagent spawn (result speaks of "my multi-angle analysis") |
| large diff | no model anywhere | completes in 34 min: 5 task_started subagents, ~2000 stream events, 15 findings, clean exit. Pipeline routes models itself: modelUsage = claude-sonnet-5 (finder bulk) + claude-opus-4-8[1m] (verify tier) |
Timeline corroboration: our CI wrapper ran /code-review max headless successfully for days on the CLI default model; failures began the exact day we added --model claude-opus-4-8[1m] (added because the CLI default had changed under us), and disappeared the moment the pin was removed.
Expected
- A top-level model override in
-pshould behave like the session model in interactive mode: apply to the orchestrator, not force the pipeline's internal per-role model routing (finders/verify/scoring). - If a subagent/orchestration step fails or stalls under a forced model, the run should fail loudly (non-zero exit, error on stderr/result), not hang forever with an empty result.
Notes
- stream-json event logs for all four cells of the matrix are available on request (init-only stall vs. 2000-event healthy run).
- Possibly related to the "review completes but result is empty" class in anthropics/claude-code-action#1087, though this case is more severe (zero events, no completion).