Bundled search wrappers narrow silently and exit 0

Status Open
Reported on v2.1.217
Maintainer reply None cached
Activity 0 comments · opened Jul 22, 2026

Environment: Claude Code 2.1.217, macOS, zsh.

Summary

The shell-snapshot functions that shadow grep (ugrep with --ignore-files --hidden -I)
and rg (bundled ripgrep with default ignore behavior) exclude gitignored, hidden, and binary
files from results. The narrowing is a reasonable default. The problem is that it is never
disclosed. The search prints its matches, exits 0, and gives no signal that any files were
skipped, so a thin or empty result is indistinguishable from an exhaustive one.

Reproduction (deterministic)

Plant a unique string in 10 files, one behind each narrowing channel (a plain file, a hidden
file, a hidden directory, a gitignored directory, a gitignored file, a gitignored glob, a
binary file, and an untracked file):

| search | files found |
|---|---|
| command grep -rl STRING . | 10 of 10 |
| wrapped grep -rl STRING . | 5 of 10 |
| wrapped rg -l STRING | 3 of 10 |

All three exit 0. None print any indication that files were skipped.

Why the silence has a cost (measured)

Two independent measurements on one user's environment:

  1. A controlled experiment: 48 runs (Claude Sonnet) against a planted corpus with a known

answer key. In the baseline condition, 25% of runs concluded a string was absent when it
was present, and stopped searching early. Transcripts show the agent's spelling and variant
hypotheses were usually correct. It trusted an incomplete, exit-0 tool result over its own
correct hypothesis.

  1. The same user's Claude Code transcripts across 74 days (41,428 tool calls, 6,398 of them

search-shaped). The rate of "empty search result, then no further search that turn" was 22
to 27% depending on the measurement window, consistent with the experiment's 25%.

This is one user's data, so treat the rates as indicative rather than fleet-representative. The
deterministic reproduction above does not depend on them.

Suggested fix (minimal)

Emit one line to stderr when a search was narrowed, for example:

note: 312 files skipped by ignore rules, 40 binary; pass --no-ignore --hidden --binary for full coverage

The narrowing can stay the default. Only the silence needs to change. A distinct exit code for
"results were narrowed" would additionally let scripts and agents branch on incompleteness
rather than reading exit 0 as a clean, exhaustive search.

View original on GitHub ↗