Overreach

Ran an irreversible command without asking

没问一声就跑了不可逆命令

The agent force-pushes, runs `rm -rf`, `git reset --hard`, or drops a table to get unstuck, and work or data is gone.

Applies to: Claude Code · Cursor · Codex · Copilot agent

Symptom

Uncommitted work vanishes, a remote branch is rewritten, a dev or production database is emptied.

Why it happens

A clean slate is a fast way past a confusing state, and the agent doesn't weigh reversibility unless forced to. agent-failure-modes lists AFM-15 Destructive Overreach; developertoolkit.ai puts unsafe agent actions under security, controlled in the session (permissions, sandbox).

Example

Illustrative.

bash
# Agent, after a merge conflict:
git reset --hard origin/main && git push --force

Copy-paste fixes

Pick the files for the agents you use. Snippets are in English so they work in any repo.

Rules

Claude Code: add to CLAUDE.md

CLAUDE.md
## Irreversible actions need a human
- Never run destructive or irreversible commands without explicit approval in this conversation:
  `rm -rf`, `git push --force`, `git reset --hard`, `git clean -f`, history rewrites, `DROP`/`TRUNCATE`,
  `DELETE` without `WHERE`, infrastructure destroy, or anything touching production.
- When stuck, stop and describe the state and options instead of wiping it.
- Before risky local operations, make a backup branch (`git branch backup/<date>`).
Rules

Codex, Copilot coding agent and others: add to AGENTS.md

AGENTS.md
## Irreversible actions need a human
- Never run destructive or irreversible commands without explicit approval in this conversation:
  `rm -rf`, `git push --force`, `git reset --hard`, `git clean -f`, history rewrites, `DROP`/`TRUNCATE`,
  `DELETE` without `WHERE`, infrastructure destroy, or anything touching production.
- When stuck, stop and describe the state and options instead of wiping it.
- Before risky local operations, make a backup branch (`git branch backup/<date>`).
Cursor rule

Cursor: project rule

.cursor/rules/destructive-command.mdc
---
description: "AgentFails: Ran an irreversible command without asking"
alwaysApply: true
---

## Irreversible actions need a human
- Never run destructive or irreversible commands without explicit approval in this conversation:
  `rm -rf`, `git push --force`, `git reset --hard`, `git clean -f`, history rewrites, `DROP`/`TRUNCATE`,
  `DELETE` without `WHERE`, infrastructure destroy, or anything touching production.
- When stuck, stop and describe the state and options instead of wiping it.
- Before risky local operations, make a backup branch (`git branch backup/<date>`).
Hook

Claude Code PreToolUse hook: stop destructive shell commands

Register with matcher "Bash". A pattern list is a seatbelt, not a sandbox; keep real backups and least-privilege credentials too.

.claude/hooks/block_destructive.py
#!/usr/bin/env python3
"""Block high-blast-radius shell commands; the agent must ask the user instead."""
import json, re, sys

call = json.load(sys.stdin)
if call.get("tool_name") != "Bash":
    sys.exit(0)
cmd = call["tool_input"].get("command", "")

dangerous = [
    r"\brm\s+-[a-zA-Z]*r[a-zA-Z]*f|\brm\s+-[a-zA-Z]*f[a-zA-Z]*r",   # rm -rf / rm -fr
    r"\bgit\s+push\b.*(--force\b|-f\b|--force-with-lease)",
    r"\bgit\s+reset\s+--hard\b",
    r"\bgit\s+clean\s+-[a-zA-Z]*f",
    r"\bgit\s+checkout\s+--\s+\.",
    r"\b(drop|truncate)\s+(table|database|schema)\b",
    r"\bdelete\s+from\s+\w+\s*;?\s*$",                              # DELETE without WHERE
    r"\b(terraform|tofu)\s+destroy\b",
    r"\bkubectl\s+delete\b",
]
for pat in dangerous:
    if re.search(pat, cmd, re.IGNORECASE):
        print(f"BLOCKED destructive command: {cmd!r}\n"
              "Explain what you want to run and why, and let the user run it or approve it.", file=sys.stderr)
        sys.exit(2)
sys.exit(0)
Settings

Claude Code permissions: hard-deny sensitive paths, ask before installs

Rules in CLAUDE.md are context; permission rules are enforced by the tool. Adjust the paths to your repo.

.claude/settings.json
{
  "permissions": {
    "deny": [
      "Edit(./migrations/**)",
      "Edit(./.env*)",
      "Edit(./package-lock.json)",
      "Edit(./pnpm-lock.yaml)",
      "Edit(./src/generated/**)"
    ],
    "ask": [
      "Bash(npm install:*)",
      "Bash(pnpm add:*)",
      "Bash(yarn add:*)",
      "Bash(pip install:*)",
      "Bash(git push:*)"
    ]
  }
}

Sources and credit

Related patterns

翻车 of the week

One real agent failure and its fix, every week. Free, short, no spam.