How to Stop an AI Coding Agent From Editing Unrelated Files
A broad instruction like fix the bug lets an AI coding agent wander into files you never mentioned. Here is the real mechanism, a worked example, and four checkable fixes.
Stop an AI Coding Agent From Editing Unrelated Files
An AI coding agent edits files outside its assigned task because it is optimizing for solving the problem, not for making the smallest possible change. Give it a broad instruction like fix the bug or improve this file, and it will sometimes rename a variable in a neighboring module, tidy an unrelated import, or reformat a function nobody asked about, because nothing in the instruction told it not to. Stopping an AI coding agent from editing unrelated files takes four things working together: instructions that name the exact files in scope, a repo-level instructions file that sets a default against touching adjacent code, a habit of checking the diff's file list before its content, and, where the tool supports it, permission or sandbox rules that block writes outside a defined path.
Why AI coding agents wander outside the task
The behavior has a specific cause. A large language model given an open-ended instruction, such as fix the bug or clean this up, is rewarded during training for producing a correct and complete-feeling solution, not for minimizing the diff. If the model notices something adjacent that looks wrong while it is working, fixing it feels like part of doing the job well.
Agentic coding tools make this worse than a plain chat model would. They can grep the whole repository, open any file, and trace a bug across module boundaries without being asked to. That is exactly what makes them useful for real debugging, but it also means the agent routinely sees code you never mentioned. Once it is looking at a file, the line between investigating and editing gets thin. A model that finds an unused import three files away from the bug it was asked to fix has no built-in reason to leave it alone unless you gave it one.
A concrete example: the date bug that also touched an import
Say you ask an agent to fix a date-formatting bug in formatInvoiceDate.ts, where invoices are showing US-style dates to customers in a region that expects day-month-year order. The agent opens the file, finds the bug, and fixes the format string. While tracing how the function is called, it opens lib/utils/currency.ts, notices an import that is not used anywhere in that file, and removes it in the same commit, because it is a real, if tiny, improvement and the agent is already there.
That second change is the risk, not the first. The date fix was the requested, reviewed, tested change. The import removal was not requested, was not the subject of any test, and now rides along inside the same commit. If currency.ts turns out to depend on that import for a side effect you did not know about, such as a polyfill or a module registration, you find out in production, not in review, because nobody was looking for a bug in a file nobody asked the agent to touch. Reverting the date fix later also means picking apart a commit that changed two unrelated files instead of one, rather than reverting a single clean change.
Four checkable ways to keep an agent in scope
Name the exact files or directories in scope
The single highest-leverage fix is also the cheapest: tell the agent which files it is allowed to change. Instead of fix the date bug, write fix the date-formatting bug in src/lib/formatInvoiceDate.ts, do not edit any other file. If the fix genuinely requires touching a second file, such as a shared date-formatting utility, name that file too, or ask the agent to stop and tell you before it edits anything outside the list. This does not require any special tooling. It is a difference in how you phrase the task, and it is checkable: when the diff lands, you already know exactly which files should appear in it.
Use a repo-level instructions file with a don't-touch-adjacent-code default
Per-task scoping works until you forget to do it, which is often. A repo-level instructions file, in the AGENTS.md or CLAUDE.md convention, fixes the default rather than relying on you remembering every time. AGENTS.md has become a common, tool-recognized location for this kind of standing instruction, read by multiple agentic coding tools, and a nested AGENTS.md in a subdirectory can scope stricter rules to just that part of the codebase. A useful line to put in the repo-level file: only edit the files needed for the stated task, do not refactor, rename, or clean up code outside that scope unless asked, and if you believe an unrelated file needs a change, say so instead of making it. That line does not need to be long to change behavior. It needs to be unambiguous, and it works alongside other standing rules, like how you want an agent to match your existing code style.
Review the diff's file list before the diff content
Most reviews start at the top of the diff and read down, which means the extra file at the bottom gets the least attention of anything in the change. Reverse that. Before reading a single line, look at the list of changed files, whether that is git diff --stat, the file tree in a pull request, or the summary an agent gives you at the end of a run. Ask one question of that list: does every file on it trace back to the task you assigned? A file you cannot explain is a scope violation, whether or not the change inside it is good on its own. Catching it at the file-list stage takes seconds. Catching it after merge takes a bisect.
Use permission or sandbox boundaries where the tool supports them
Instructions and instructions files are still requests. A determined or confused agent can still ignore them. Where the coding tool supports it, back the request with an enforced boundary instead of a written one. Claude Code, for example, lets you define allow, deny, and ask rules in a settings file using a tool-and-specifier format, evaluated deny-first, so a deny rule for edits outside a given path overrides a broader allow rule. Its sandbox mode goes further, restricting what a shell command run by the agent can write to at the operating-system level rather than trusting the model to comply. The specifics vary by tool, and how much control you get is one more thing worth weighing when you are picking which agentic coding tool to standardize on. But the pattern generalizes: wherever a permission or sandbox layer exists, moving the boundary from the prompt into the tool's enforcement removes an entire class of accidental edits, not just the ones caused by an overly broad instruction. It is also the same kind of control worth setting deliberately across a team, not just for one person's local setup.
A short pre-merge checklist
Check | Why it matters |
|---|---|
File count matches what you asked for | Any extra file is either a mistake or something worth a conversation, not a silent pass |
Every changed file traces to the stated task | If you cannot say why a file changed, treat it as scope creep until proven otherwise |
No unrelated renames or reformatting mixed in | Reformatting inflates the diff and hides the change that actually matters |
New files were discussed, not just discovered at review | An agent creating a file you did not ask for is often exploring past its scope, not fixing the bug you assigned |
The same discipline that keeps an agent from editing unrelated files also keeps it from quietly adding a dependency you did not choose, or making decisions your reviewer never sees. The fix in both cases is the same: name the scope, enforce it where the tool lets you, and read the file list before the diff. If you are still choosing between agentic coding tools, how each one handles permissions and sandboxing is worth weighing before you standardize on one.
Questions
Why does an AI coding agent touch files outside what I asked for?
Because a broad instruction rewards a solution that feels complete, not one that is minimal. Agentic tools can browse and grep an entire repository without being asked to, so once an agent notices something adjacent while investigating, fixing it can feel like part of finishing the job unless the instruction or a standing rule tells it otherwise.
Does naming the exact file in my instruction fully stop this?
It removes most of it, but not all. A file-level instruction is still a request the model can misjudge, especially if the fix genuinely needs a second file. Pair it with a repo-level instructions file and a habit of checking the file list on every diff, so a slip gets caught before merge, not after.
Can I actually block an agent from writing to certain paths?
It depends on the tool. Some agentic coding tools let you define permission rules or sandbox restrictions that block file writes outside an approved path at the tool or operating-system level, rather than relying on the model to follow a written instruction. Check whether your specific tool exposes that kind of setting before assuming a plain-text rule is your only option.
Should I reject every pull request that includes an unrelated cleanup?
Not automatically, but treat it as a decision, not a default. A one-line unrelated cleanup might be fine to accept on its own merits. The problem is when it rides along untested inside a commit whose message and review attention are both about something else. Splitting it into its own change, or asking the agent to leave it out, keeps the two decisions separate.
How did this land?
About the author

Developer Advocate
Steve builds something with Swarmz every week and writes up what worked, what broke, and what he'd do differently. Tutorials and hands-on guides are his lane.


