[BUG] Opus 4.6 having a lot of trouble with read -> edit tool spaces and tabs due to diff seperator
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Opus 4.6 reports:
_The issue was that the Read tool's display uses tabs after line numbers, but the → separator was
misleading me about the actual content start position. The Edit tool matches the raw content without
line number prefixes. Now let me format this file and move on to the next changes._
Opus 4.6 often asks to use sed and then awk on Mac/bash and I do not allow it, instead asking it why (I also have it prefer tools over sed in my CLAUDE.md as this was happening a lot in 4.5). In this case it kept saying that one tool was reading tabs and another was displaying spaces, causing it to attempt edits a number of times and different ways.
What Should Happen?
The read -> edit tool use should just work the first time.
Error Messages/Logs
Steps to Reproduce
It happens intermittently. I was working on a React component and the JSX section seemed to be where it was editing.
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.33
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
VS Code integrated terminal
Additional Information
Longer snippit of the conversations:
...the Edit tool should handle tab-indented files. Let me re-read the file at those specific lines to get
the exact content the Edit tool sees, then match it precisely.
⏺ Read 1 file (ctrl+o to expand)
⏺ I see the line numbers show the content after a tab separator. The content at line 533 starts with
10 tabs, then disabled={isUsedByOther}. The Edit tool requires exact string matching including tabs.
Let me construct the old_string with literal tabs. The → in the Read output represents the tab
between line number and content - everything after that is the actual file content.
Looking at the od output: line 533 has 10 tab chars before disabled. Line 534 has 10 tab chars
before sx. The JSX lines 530-534 use 9-10 tab indentation levels.
Let me try a very small, unique match — just the two lines that need to change, using the disabled
prop which appears only 3 times:
⏺ Update(src/components/-------/------.tsx)
⎿ Added 12 lines, removed 6 lines
530 <MenuItem
531 key={key}
532 value={key}
533 - disabled={isUsedByOther}
534 - sx={{ pl: 2.5 }}
533 + sx={{
534 + pl: 2.5,
535 + ...(isUsedByOther && { color: 'primary.main' }),
536 + }}
537 >
538 {mapping.label}
539 </MenuItem>
...
560 <MenuItem
561 key={key}
562 value={key}
561 - disabled={isUsedByOther}
562 - sx={{ pl: 2.5 }}
563 + sx={{
564 + pl: 2.5,
565 + ...(isUsedByOther && { color: 'primary.main' }),
566 + }}
567 >
568 {mapping.label}
569 </MenuItem>
...
590 <MenuItem
591 key={key}
592 value={key}
589 - disabled={isUsedByOther}
590 - sx={{ pl: 2.5 }}
593 + sx={{
594 + pl: 2.5,
595 + ...(isUsedByOther && { color: 'primary.main' }),
596 + }}
597 >
598 {mapping.label}
599 </MenuItem>
⏺ The issue was that the Read tool's display uses tabs after line numbers, but the → separator was
misleading me about the actual content start position. The Edit tool matches the raw content without
line number prefixes. Now let me format this file and move on to the next changes.
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗