#21701: fix(agents): handle JSON array output from Claude Code CLI
agents
size: XS
Cluster:
Session Management and Fixes
## Summary
- `parseCliJson()` in `src/agents/cli-runner/helpers.ts` fails when Claude Code v2.1.49+ outputs a JSON array instead of a single JSON object
- `isRecord(parsed)` rejects arrays, returns `null`, and the raw JSON gets dumped as the message text to Discord/Telegram
- Added array handling: iterates entries for session ID and usage, prefers the `"result"` entry, falls back to `"assistant"`
## Problem
Claude Code `--output-format json` now outputs:
```json
[
{"type": "system", "subtype": "init", ...},
{"type": "assistant", "message": {...}, ...},
{"type": "result", "result": "response text", "session_id": "...", ...}
]
```
But `parseCliJson()` only handled single JSON objects. The `isRecord()` check rejected arrays, causing `null` return and raw JSON fallback.
## Test plan
- [x] Tested with Claude Code v2.1.49 via OpenClaw CLI runner (`claude-cli/opus`) on Discord
- [x] Before fix: raw JSON array dumped as Discord message
- [x] After fix: clean text response with proper session ID and usage stats
- [ ] Verify backward compatibility with single-object JSON output (older Claude Code versions)
- [ ] Verify no regression for Codex CLI backend
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Adds support for Claude Code CLI v2.1.49+ JSON array output format to prevent raw JSON from being dumped to Discord/Telegram. The parser now handles both array and single-object formats, iterating through array entries to extract session ID, usage stats, and response text from the appropriate entry type (`"result"` preferred, `"assistant"` as fallback). Backward compatibility with older single-object output is preserved.
<h3>Confidence Score: 5/5</h3>
- Safe to merge - well-structured fix with preserved backward compatibility
- The fix correctly handles the new array format while maintaining backward compatibility with single-object JSON. Logic properly iterates entries, prefers `result` over `assistant` type, and collects session/usage metadata. Only minor style issue found (redundant type check).
- No files require special attention
<sub>Last reviewed commit: 9ffb1f7</sub>
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#23720: Feat/cli backend runtime tuning
by wanmorebot · 2026-02-22
74.4%
#11996: fix: CLI backend JSON array parsing and clearEnv merge
by shanemmattner · 2026-02-08
73.6%
#19136: feat(claude-code): implement spawn mode for Claude Code sub-agents
by botverse · 2026-02-17
71.4%
#4767: fix(agents): handle read alias required schema
by RomeroYang · 2026-01-30
71.1%
#18179: CLI: add sessions --json-debug diagnostics
by p6l-richard · 2026-02-16
70.7%
#12384: feat(cli): add --stream-json flag for live NDJSON streaming
by kumarabhirup · 2026-02-09
70.6%
#11141: Fix JSON schema conversion error when using llama.cpp backend
by 9nix00 · 2026-02-07
70.5%
#15522: fix(codex-cli): compatible resume args + JSONL chunk streaming bridge
by chungjchris · 2026-02-13
70.5%
#2071: fix: accept JSON string for cron.add job parameter (#1940)
by andrescardonas7 · 2026-01-26
70.4%
#16685: Fix cli agents/approvals/discord routing edge cases
by craftowen · 2026-02-15
70.2%