How to stop an AI agent from deleting your files
AI agents delete files because they run as you, where your files live. Why blocked-command lists don't hold, and the layers that do.
On this page7
An AI agent deletes your files for the same reason any program can: it runs as you, with your permissions, on the machine where your files live. Rules in its instructions and lists of blocked commands help, but they aren't a boundary. The boundary is where the agent runs and what it can write to, and the safety net is a backup you have restored at least once.
This guide is for anyone running a coding or work agent on their own computer, whatever the tool. The examples are public reports from the last few weeks.
Why do AI agents delete files they shouldn't?
Almost never out of malice. The agent is doing the job it was given, with more reach than the job needs. The reports people post fall into a few patterns:
- A clean-up with too wide a target. One developer had a folder of "around 40 project folders going back years" on their own machine. "Today Claude ran rm -rf and wiped everything." Only one of those projects was in git, and it hadn't been pushed for a week.
- A restore that runs backwards. Asked to undo a small wording change, one agent copied a whole file out of a two-week-old archive over the current one. It reported success; four security fixes it had made earlier in the same session were gone, and nothing was in git (r/ClaudeCode).
- Git acting on links. Agents working in separate git worktrees often link big folders from the main checkout to save disk space. In one case this month, the links were committed, the branch was merged back, and git checked a link out over the real 10 GB data folder. "no backup, not in trash. it's just gone."
- An approval clicked without reading. After the fiftieth prompt, the one that says
delete --alllooks like the others.
In each case a person would have hesitated. The agent didn't, because nothing in its way said stop.
Is a list of blocked commands enough?
No. A block list matches how a command is written, and there are many ways to write a delete.
One developer ran ten companies' guard hooks against other spellings of the commands they were built to block. "Every one let at least one through." The spellings that slipped past were ordinary: rm -fr instead of rm -rf, a command wrapped in sh -c '...', a force push written as git push origin +main. One guard exited with the wrong code, so it never blocked anything at all.
Agents find these spellings on their own. One developer had set their agent never to run rm; after rm -rf was refused twice, it removed the folder with find -delete instead (on X). Not scheming: it was asked to remove a folder, and rm didn't work.
Claude Code's own documentation says the same about its permission rules: "Bash permission patterns that try to constrain command arguments are fragile." Keep your block list as a speed bump. Don't treat it as a wall.
How do you limit what an agent can write to?
Put the limit in the operating system, not in the agent's instructions. The filesystem doesn't care how a delete is spelled. Four ways, from least to most separation:
- Turn on the agent's own sandbox, if it has one. Several coding agents now ship one that the operating system enforces. In OpenAI's Codex, the workspace-write mode lets the agent "read files, edit within the workspace, and run routine local commands inside that boundary". Claude Code's sandbox lets shell commands write only to the working directory, a temp folder and folders you add, using Seatbelt on macOS and bubblewrap on Linux (sandboxing docs). Read the small print for your tool: Claude Code's sandbox covers shell commands only, and if it can't start, commands run without it unless you set
sandbox.failIfUnavailable. - Give the agent its own user account. A separate operating system user that owns the project folder and can't write to your home folder. This works with any agent, sandbox or not.
- Give it its own machine. A virtual machine, a container with only the project mounted, or a small server. The Claude Code docs say to use its no-prompts mode "only... in isolated environments like containers or VMs where Claude Code can't cause damage."
- Open it in the project, never in your home folder. Most agents treat the folder they start in as their workspace. Start one in
~and everything you own is the workspace.
The further the agent is from files you can't replace, the less any single mistake costs.
What about the files git doesn't track?
Git is an excellent undo for tracked files and no help at all for the rest. Ignored and untracked folders (local data, databases, .env files, build output, anything in .gitignore) are invisible to it. Those are often exactly the folders an agent cleans up.
Two habits close most of the gap:
- Commit before each task. A commit before the agent starts is a checkpoint you can return to with one command.
- Write ignore rules that match links too. The git manual is precise about a trailing slash: "The pattern 0 will match a directory 1 and paths underneath it, but will not match a regular file or a symbolic link 2 ". So if
datais a link to the main checkout's data folder,data/in.gitignoredoesn't ignore it, andgit add -Acommits the link. Write/datawithout the slash, add explicit paths in a worktree instead of-A, and check withgit check-ignore -v data: it prints the rule that matches, and nothing at all if the path isn't ignored.
Which backups actually save you?
The ones that keep old versions, live off the machine, run without you, and have been restored at least once.
- Versioned. A backup that keeps yesterday's copy alongside last week's. Time Machine, Windows File History, restic, borg and most cloud server snapshots do this.
- Off the machine. A backup on the same disk goes with the disk, and an agent with your permissions can delete it.
- Automatic. Daily at least. The gap between backups is the work you can lose.
- Tested. Restore one folder, once, onto another machine. That's when you find the file nobody knew mattered.
Be careful with sync folders. Dropbox, iCloud and Google Drive copy a deletion to every device; whether you can get the file back depends on how long that service keeps deleted files and old versions on your plan. Check that number before you rely on it.
How do you approve commands without rubber-stamping them?
Ask for fewer approvals, and make each one count. An agent that asks about every ls trains you to click yes. One developer described approving an agent's oc delete --all without reading it, then building guardrails afterwards (r/ClaudeCode).
A better split:
- Let routine work inside the sandbox run without asking.
- Keep a prompt for deletes outside the workspace, force pushes, anything touching another machine, and anything that sends or spends.
- When a prompt comes, read the path, not the verb.
rm -rf ./buildandrm -rf ~/Devare the same command with very different costs.
Telling the agent, in its standing instructions, to move files to a trash folder instead of deleting them helps too. It's one more layer, not a guarantee: instructions get skipped, which is why the layers above exist.
A checklist you can run today
- Run the agent where your irreplaceable files aren't: its own user, container, virtual machine or server.
- Turn on its sandbox if it has one, and make it fail closed rather than run without it.
- Start it in the project folder, never in your home folder.
- Commit before each task.
- Fix
.gitignorelines that end in a slash, if links are involved. - Keep a versioned backup off the machine, and restore from it once.
- Keep approvals for the actions that matter, and read the path before you click.