[BUG] rg tool-output rendering intermittently replaces matched substrings with short tokens (emitted bytes are clean)
Summary
In the native macOS Claude Code TUI, the rendered output of rg (ripgrep) tool
calls intermittently replaces a matched substring with a short, unrelated
token — e.g. storage → in, gsutil → l, gs:// → l. Only the
matched term is corrupted; surrounding text is intact, and the underlying file
is unaffected. It is intermittent: the same command renders correctly on other
runs.
Environment
- Claude Code: 2.1.217 (native macOS build)
- macOS: 26.5.2 (25F84), Apple Silicon
- Terminal: Ghostty (
TERM=xterm-ghostty) - ripgrep invoked via the Bash tool, e.g.
rg -n 'storage' file.py
Evidence it is the renderer, not ripgrep
The bytes ripgrep emits are clean ASCII with no color/escape sequences:
rg -n 'storage' file.py | od -c→ pure ASCII,s t o r a g everbatim, **no
\033/SGR bytes**.
RIPGREP_CONFIG_PATH,NO_COLOR,CLICOLOR_FORCEare all unset; piped
stdout means --color=auto resolves to off.
- Forcing
--color=alwaysshows the display strips the ESC byte but leaves the
SGR params literally ([0m[1m[31mstorage[0m) — confirming an escape-handling
path exists — yet the substring corruption also occurs with plain,
non-colored output (bytes verified via od -c).
So ripgrep's output is provably correct; the substitution happens in Claude
Code's tool-result rendering layer.
Observed instances (single session)
storagerendered asin(e.g.active volumes (storage)shown as
active volumes (in); === johten volumes (storage, billed ... shown as
... volumes (in, billed ...)
gsutilandgs://both rendered asl(e.g.gsutil -m rsyncshown as
l -m rsync; gs://bucket/... shown as lbucket/...)
- A separate session reported the replacement token
n
Pattern: only the matched substring is replaced, consistently within a single
invocation, with a short token.
Repro (intermittent)
rg -n '<term>' <file>where<term>occurs several times.- Occasionally the matched
<term>renders as a short token (in,l,n)
instead of the real text.
rg -n '<term>' <file> | od -con the same command shows the emitted bytes
are correct — so the corruption is purely in rendering.
I could not find a deterministic trigger; it appears tied to match highlighting
and is not reproducible on demand.
Impact
Agents (and users) that act on the rendered matched text — renames, path
edits, quoting identifiers — can silently use a wrong string, because the
corruption reads as legitimate content. File contents are never affected, but a
model driving an edit off the rendered token can make an incorrect change.
Not a duplicate of
The existing garbling issues I found are CJK/Unicode mojibake (encoding) or
general TUI overwrite/redraw. This is ASCII match-substring substitution with
provably clean underlying bytes — a distinct rendering-layer defect specific torg match output.
This issue has 1 comment on GitHub. Read the full discussion on GitHub ↗