[BUG] "No messages returned" error crashes CLI in --print mode with unhandled promise rejection
Description
When using Claude Code CLI in --print mode with --output-format json, the CLI intermittently crashes with an unhandled promise rejection error "No messages returned". This occurs when the Claude API returns an empty or malformed response.
The error is not gracefully handled - it throws an unhandled promise rejection that terminates the process, making it difficult for automation tools to implement retry logic.
Environment
- Claude Code version: 2.1.12
- Node.js version: v22.17.0
- OS: macOS 15.3 (Darwin 25.2.0) arm64
- Installation method: npm global
Steps to Reproduce
- Run Claude Code in print mode with JSON output repeatedly (the error is intermittent):
claude --print \
--input-format text \
--output-format json \
--json-schema '{"type":"object","properties":{"summary":{"type":"string"}},"required":["summary"]}' \
--model sonnet \
--dangerously-skip-permissions \
"Your prompt here"
- Run this in a loop or via automation (the error occurs intermittently, approximately 1% of runs in my testing)
- Eventually, one of the runs will fail with the error below
Error Output
This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason:
Error: No messages returned
at GO9 (file:///Users/tom/.nvm/versions/node/v22.17.0/lib/node_modules/@anthropic-ai/claude-code/cli.js:5388:647)
at process.processTicksAndRejections (node:internal/process/task_queues:105:5)
Expected Behavior
When the API returns no messages (empty response), the CLI should:
- Not crash with an unhandled promise rejection - this makes it impossible to catch the error in wrapper scripts
- Return a proper error result in JSON format when using
--output-format json, such as:
{
"type": "result",
"subtype": "error_during_execution",
"is_error": true,
"errors": ["API returned no messages - possible transient failure"],
"session_id": "..."
}
- Exit with a non-zero exit code (which it does, but via crash rather than graceful exit)
Actual Behavior
- The CLI throws an unhandled promise rejection
- The process crashes without returning valid JSON output
- No session data is written (making recovery impossible)
- The exit code is non-zero but the crash is ungraceful
Impact
This bug significantly impacts automation tools that use Claude Code CLI:
- Zeroshot (multi-agent orchestration tool) spawns multiple Claude Code processes. When this error occurs, the worker process crashes and the parent orchestrator hangs waiting for a response that will never come.
- Any automation using
--printmode in loops will fail unpredictably - There's no way to implement retry logic because the error is an unhandled rejection
Root Cause Analysis
Looking at the minified source at cli.js:5388, the error is thrown here:
let O=mE(L);
switch(X.outputFormat){
case"json":
if(!O||O.type!=="result")throw Error("No messages returned");
The condition !O || O.type !== "result" throws when:
- The message array
Lis empty - The last message
O = mE(L)is undefined or not a result type
This can happen when the Claude API returns an empty response due to:
- Transient network issues
- Rate limiting edge cases
- API instability
Suggested Fix
Instead of throwing, handle this case gracefully:
case "json":
if (!O || O.type !== "result") {
const errorResult = {
type: "result",
subtype: "error_during_execution",
is_error: true,
errors: ["No messages returned from API"],
session_id: g1(),
// ... other required fields
};
R2(dA(errorResult) + "\n");
O4(1);
return;
}
Frequency
In my testing with ~300+ CLI invocations over a few hours:
- 3 failures with this exact error
- Failure rate: ~1%
- Failures occurred at different times (3 hours apart, then 18 minutes apart)
- No clear pattern correlating with prompt size or content
Workaround
Currently, no reliable workaround exists because:
- The error is an unhandled promise rejection (can't catch in bash)
- No session data is written before the crash (can't recover output)
- The error message goes to stderr but the process still crashes
Additional Context
This is being reported in the context of using Claude Code with the Zeroshot multi-agent orchestration tool, but the bug affects any automation using --print mode.
Log files from affected runs are available if needed for debugging.
This issue has 8 comments on GitHub. Read the full discussion on GitHub ↗