Claude Code Edited the Wrong File

Modified a file you didn't intend — usually similar names, or it followed an import chain. Git-revert, then re-scope with allow/deny lists in the prompt.

You said “edit src/auth/login.ts.” Claude edited src/auth/logIn.ts (different casing — a stale file you forgot existed). Or it edited src/auth/login.test.ts thinking that’s where the bug was. Or it edited src/legacy/auth/login.ts because that name matches and it found it first.

Wrong-file edits come from two failure modes: ambiguous naming (multiple candidates match the description) or scope drift (agent followed imports/calls beyond what you asked). The fix is the same in both cases: explicit allow/deny lists in the prompt, plus git-revert + re-scope when it happens.

Common causes

Ordered by hit rate, highest first.

1. Two files with similar names — agent picked wrong one

login.ts and Login.ts, auth.service.ts and auth.test.ts, user.ts and users.ts. Without explicit disambiguation, the agent picks whichever surfaced first in its file scan.

How to spot it: find . -iname "login*" returns multiple candidates. Without a path, “login” is ambiguous.

2. Agent followed an import chain into an adjacent file

You said “fix billing.ts.” It read billing.ts, saw import { format } from "../utils", decided the issue was in utils.ts, and edited there.

How to spot it: Diff includes a file in utils/, lib/, or common/ even though your task was specific to a feature.

3. Agent did a “small cleanup” of an adjacent file

While editing the target, it noticed the next-door file had a typo or inconsistent style and “fixed” it. Adjacent files end up in the diff.

How to spot it: Diff has 2-3 small unrelated changes in files near the target. Each looks innocuous; together they’re scope creep.

4. Naming ambiguity from monorepo or duplicate folders

apps/web/src/auth/login.ts and packages/shared/auth/login.ts both exist. Agent picked whichever path appeared first in its tool calls.

How to spot it: Diff is in a different package than you intended. Same filename, different ancestor folder.

5. Agent edited the test file thinking it was production code

login.test.ts mocks call login() — the agent saw the mock setup, thought it was production, and edited the mock instead of the real implementation.

How to spot it: Diff is in a .test.ts / .spec.ts file even though you asked for a production fix.

6. Case-insensitive filesystem confusion

On macOS (case-insensitive), Login.ts and login.ts are the same file. On Linux CI (case-sensitive), they’re different. The agent’s edit can land in the wrong canonical form depending on the platform.

How to spot it: Same content, different casing in the path. Check git log --follow for any renames.

Shortest path to fix

Ordered by ROI. Step 1 recovers; Step 2 prevents recurrence.

Step 1: Inventory the damage with git status + git diff

# What changed?
git status

# Detailed diff
git diff --stat
git diff

For each unintended file, revert:

# Single file
git checkout HEAD -- src/wrong/file.ts

# Multiple files
git checkout HEAD -- src/wrong/ src/another-wrong/

# If you already committed
git revert <commit-hash>

Step 2: Re-prompt with explicit allow + deny lists

EDIT exactly these files (and no others):
- src/auth/login.ts

DO NOT touch any of these (even if you think they need changes):
- src/auth/Login.ts (deprecated, do not revive)
- src/auth/login.test.ts (test file, separate concern)
- src/legacy/ (entire directory is off-limits)
- src/utils/ (shared, requires separate approval)

If the task requires editing anything else, STOP and ask.

The deny list is critical — it catches “agent thought it was helping” cases that the allow list doesn’t.

Step 3: Use absolute paths in prompts, not “the auth file”

Bad: "fix the auth file"
Good: "fix `apps/web/src/auth/login.ts`"

A full path eliminates name-resolution ambiguity. Always include the workspace prefix in monorepos.

Step 4: For ambiguous filenames, audit and consolidate

If your repo has multiple files with similar names:

# Find lookalikes
find . -iname "login*" -not -path "*/node_modules/*"

# Resolve: delete the deprecated, rename the test, etc.
git rm src/auth/Login.ts  # if truly dead
mv src/auth/login.test.ts src/auth/login.spec.ts  # if disambiguation helps

Codebases with naming hygiene have fewer wrong-file edits.

Step 5: For dangerous areas, use a feature branch + worktree

# New branch for the agent task
git checkout -b feature/auth-fix
# Or a separate worktree to isolate
git worktree add ../project-agent feature/auth-fix

If the agent edits the wrong file, you can throw away the whole branch / worktree without affecting main.

Step 6: Add CLAUDE.md “do not touch” defaults

For files that should never be edited by agents:

## Files agents must not edit

- `migrations/*.sql` — historical record, do not modify
- `legacy/` — frozen, do not touch
- `*.snap` (snapshots) — only update via test re-run, never by hand
- `pnpm-lock.yaml` — only update via `pnpm install`, never by editing
- `dist/`, `build/` — generated, do not edit
- `.env*` — secrets, never edit

If a task seems to need editing any of these, STOP and ask.

These standing rules catch errors the per-task allow/deny list might miss.

Prevention

  • Use absolute paths in prompts, not descriptions; “src/auth/login.ts” not “the auth file”
  • Every non-trivial prompt includes an allow + deny list of files
  • CLAUDE.md has standing “do not touch” rules for migrations, snapshots, lockfiles, generated output
  • Audit your repo quarterly for confusing duplicate-case or near-name files; consolidate
  • Run risky agent work on a branch / worktree so revert is one command
  • For monorepos, always include the workspace prefix to disambiguate cross-package collisions

Tags: #Troubleshooting #Claude Code #Debug #Wrong edit