Repository navigation
Open
Description
Bug
/codex:review (both foreground and background) fails with a JSONL parse error when the Codex CLI outputs terminal escape sequences (bracketed paste mode) that corrupt the JSON stream.
Error
Failed to parse codex app-server JSONL: Unexpected token '', "[?2004h" is not valid JSON
Reproduction
- Authenticate with
codex login - Have a working tree with staged/unstaged changes
- Run
/codex:reviewfrom Claude Code (either foreground or background mode) - The companion script (
codex-companion.mjs) attempts to parse the Codex CLI stdout as JSONL - Terminal escape sequence
[?2004h(bracketed paste mode) is included in the output, breaking JSON parsing
Both foreground and background execution produce the same error:
# Foreground
node "codex-companion.mjs" review
# → Failed to parse codex app-server JSONL: Unexpected token '', "[?2004h" is not valid JSON
# Background (via Claude Code Bash tool with run_in_background: true)
node "codex-companion.mjs" review
# → Same errorRoot Cause
[?2004h is the ANSI escape sequence for enabling bracketed paste mode, typically emitted by shells (bash/zsh) during initialization. When the Codex CLI spawns a subprocess or the shell environment leaks these escape codes into stdout, the JSONL parser in the companion script receives non-JSON data and fails.
This likely happens because:
- The user's shell profile (
.zshrc/.bashrc) emits escape sequences on startup - The Codex CLI subprocess inherits the terminal settings and outputs control sequences
- The companion script does not strip ANSI escape sequences before parsing JSONL lines
Suggested Fix
Strip ANSI escape sequences from the Codex CLI output before attempting JSONL parsing. For example:
// Before parsing each line as JSON
const ansiRegex = /\x1b\[[0-9;]*[a-zA-Z]|\x1b\][^\x07]*\x07/g;
const cleanLine = rawLine.replace(ansiRegex, '').trim();
if (!cleanLine) continue; // skip empty lines after stripping
const parsed = JSON.parse(cleanLine);Environment
- macOS 15.5 (Darwin 24.6.0)
- Claude Code (CLI)
- Node.js (via Claude Code Bash tool)
- Shell: zsh
- codex-plugin-cc: latest
- Codex CLI: authenticated and working (
codex loginsuccessful)
Additional Context
- Other review-related issues (Review fails due to unknown sandboxing variant #3 sandbox variant, EISDIR crash in working-tree review when untracked directories exist #14 EISDIR, The Codex plugin review erros because it can't execute shell commands due to bwrap permissions. #18 bwrap) are unrelated — this is a pure output parsing issue.
- The review job log shows
Starting Codex Review.and then immediately fails, suggesting the error occurs during the initial JSONL handshake with the Codex app-server.
Reacted by Toshiki Teramura and Haili Zhang
Metadata
Metadata
Assignees
Labels
No labels
Activity
fix: strip ANSI escape sequences before JSONL parsing
fix: strip ANSI escape sequences before JSONL parsing
fix: strip ANSI escape sequences from JSONL before parsing
fix: strip ANSI escape sequences from JSONL lines before parsing
deepak-imh commentedon Apr 7, 2026
Fix submitted in #171.
Root cause: Shells (zsh/bash) emit terminal control sequences like
\e[?2004h(bracketed paste mode) into subprocess stdout during initialization. The JSONL protocol reader passes these directly toJSON.parse(), which fails.Fix: Adds a
stripAnsi()utility that removes CSI and OSC escape sequences beforeJSON.parse()in both parsing paths (app-server.mjshandleLine +app-server-broker.mjssocket handler). 7 new tests, all 73 existing tests pass.equilibriumweb commentedon Apr 14, 2026
Still reproducing on plugin version
1.0.2today. Ping on #171 — the fix is ready and this bug currently blocks/codex:reviewand/codex:adversarial-reviewend-to-end for users on zsh.Environment
openai/codex-plugin-cc@1.0.2/bin/zsh(default)v24.8.0Reproduction
Same failure on
adversarial-reviewsubcommand. Both foreground and background modes via Claude Code's Bash tool fail identically, since both share the companion script's JSONL parser.Workaround today is running a manual self-review or asking Claude to do a static review — neither substitutes Codex's value.
Would appreciate getting #171 merged and cutting a
1.0.3release. Happy to test the fix against my repro once released.feat(jsonl): manual port of upstream PR #24 + openai#311 (ANSI strip …
docs(ultraplan): handoff §4.4 current limitations + §5 B2 re-verifica…