You asked Claude Code to fix a function near the bottom of a 4,000-line file, and it either says the code isn’t there, or it writes a brand-new version instead of editing the one that already exists — as if the second half of the file doesn’t exist to it. If you’ve searched “claude code says it can’t find code that’s there,” “claude code duplicated a function,” or “claude code edit tool string not found,” this usually isn’t a hallucination. It’s a read limit you didn’t know was in effect.
Why this happens
Claude Code’s file-reading tool doesn’t load an entire file into context by default — it reads up to a fixed number of lines (2,000) starting from the top, unless the read explicitly asks for a specific range further in with an offset. For a typical source file that’s the whole thing and you’d never notice. For a large one — a long log dump, a generated bundle, a big JSON fixture, a legacy file nobody’s ever split up — the read stops partway through, and everything past that point simply isn’t part of what the model is working from for that turn.
The dangerous part isn’t that it fails loudly. Claude doesn’t always flag that it only saw the first 2,000 lines — from its own perspective it read “the file” and got a result back, so it can answer as if that result were complete. Ask it to add error handling to a function past line 2,000 and it may write a plausible-looking new function near the top instead of editing the real one further down, or an Edit tool call can fail with “string not found” against text that’s visibly in the file in your own editor — just not in what Claude actually read.
How to tell if this is your bug
- Check the file’s real size:
wc -l <file>. If it’s comfortably under 2,000 lines, this isn’t your issue — look elsewhere. - If it’s larger, look at what got read. A large-file read typically comes back with a note about how many more lines follow, or shows Claude specifying a narrow line range when you expected the whole file.
- Ask directly: “what’s on line 2,500 of this file?” If Claude doesn’t know, or has to re-read to answer, the earlier turn didn’t have that content in context.
- If an edit failed with “string not found” and you can see the string yourself well past the file’s midpoint, that’s the read limit, not a typo in the match text.
The fix
Point Claude at the section you care about, not the top of the file. For files you know are large, don’t rely on the default read — give a line number range, or a distinctive string near the section, so the read starts where the relevant code actually is instead of at line 1.
Ask it to search before it reads. Having Claude grep or search for the function or section name first, then read from around that match, is more reliable than asking it to “read the whole file” and hoping the default range happens to cover what matters.
Expect multiple reads for genuinely large files. If you need Claude working with the full contents of a several-thousand-line file across a session, say so explicitly — that content needs to be paged in over more than one tool call, not skimmed in one.
Keep hand-edited logic out of huge generated files. For minified bundles, lockfiles, and large fixtures, don’t ask Claude to reason about the whole file at all — point it at the specific section, or restructure so logic you actually edit doesn’t live inside something that size.
Verify it’s actually fixed
Ask Claude to quote the exact lines at the location you care about — not a paraphrase, the literal text. If it can produce that correctly, the relevant section is actually in context. Then let it make the edit and check the diff lands at that location in the file, not as a second, duplicate definition near the top.
Comments
Sign in to join the conversation.
No comments yet — be the first.