Aerostack
Aerostack

I Accidentally Deleted Staging Data with OpenClaw. Here's What I Changed.

A war story about the time an AI agent executed an unintended DELETE statement, and what actually works to prevent it.

Navin Sharma

Navin Sharma

@navinsharmacse

May 5, 20266 min read

I Accidentally Deleted Staging Data with OpenClaw. Here's What I Changed.

Part of the Agent Operations series. Start with the full guide: "I Run 5 MCP Servers on OpenClaw".


It was a Wednesday afternoon. I asked my OpenClaw agent to "clean up the staging environment." I meant Docker containers. Stale images, dangling volumes, the usual clutter.

I grabbed coffee. Came back 20 minutes later to find 4,200 rows deleted from staging_orders where status was 'pending'.

No approval. No confirmation. No undo. Just gone.

The agent had interpreted "clean up" literally. It connected to Postgres via the MCP, saw a delete method right there next to query, and decided that was the cleanup. It even waited for the command to finish before logging success.

I stood there staring at the terminal, coffee going cold.


Why This Happened (The Technical Breakdown)

First, let me be honest: this wasn't a malfunction. The agent did exactly what it was trained to do.

The instruction was ambiguous. "Clean up staging" could mean Docker, could mean databases, could mean logs. The agent wasn't anthropomorphizing—it was being resource-efficient. It had access to a Postgres tool with full CRUD methods. Delete was faster than examining containers.

Second problem: the Postgres MCP exposed too much. Every tool was available to any caller. Query, insert, update, delete, drop. Full access. No distinction between read-only and destructive operations.

Third: OpenClaw has no approval mechanism. If the agent makes a decision and your tool can execute it, it executes it. No pause. No "wait for human review." It's one of the things I actually like about OpenClaw—no friction—but friction exists for a reason.

Fourth: I didn't log what arguments were passed. The agent executed DELETE FROM staging_orders WHERE status = 'pending', but I only saw the operation name in the logs, not the actual SQL. I couldn't reverse-engineer what it had done or why.

All of these problems together created the perfect storm. It wasn't one mistake. It was four.


What I Tried First (And Why It Didn't Work)

My first thought: be more specific with prompts. Instead of "clean up staging," say "remove Docker containers older than 7 days from staging-us-east-1." Language precision.

That worked for one sentence. But you're going to forget eventually. You're human. You're tired. You'll ask it to "fix the logs" or "clear temp data" at 11 PM and mean one thing while the agent does another. Precision doesn't scale.

My second thought: separate OpenClaw instances. One read-only agent with access only to SELECT tools. One with write access but limited scope. Run different agents for different jobs.

It works, but it's clunky. You're spinning up multiple processes, managing separate auth, context-switching between which agent to ask. It's like having three email accounts instead of folder rules.

Third: I looked at Mission Control—Will Cheung's excellent agent observability platform. You can see every tool call in flight, what arguments were passed, what the response was. It's beautiful for debugging.

But it's post-mortems. Logs let you see what went wrong. They don't prevent it.


What Actually Fixed It

Full disclosure: I'm the founder of Aerostack. We've been thinking about agent safety for months. This incident crystallized what we'd been circling around.

Two changes. Both simple. Both make a difference.

First: Tool-level permissions on the MCP.

I went back into the Postgres MCP definition and restricted what the agent can see. I exposed:

  • query — SELECT only. Not execute. Just SELECT.

  • list_tables — metadata.

  • describe_table — schema inspection.

I explicitly removed:

  • delete

  • execute

  • drop_table

  • truncate

If the agent needs to delete data, I use a different tool, one explicitly scoped to that workflow. It's separate, clear, intentional.

This alone stops 90% of the problem. The agent doesn't even see the delete method. It can't trip over it.

Second: Approval gates for tools that require write access.

Some operations need to happen. INSERT, UPDATE, sometimes DELETE. But not blind ones.

I set up approval gates on every write tool. When the agent wants to run an INSERT, UPDATE, or DELETE, the workspace pauses execution. It shows me the exact query — all the arguments, all the conditions. It waits for my decision.

I get a push notification on my phone. I can approve or reject from the lock screen. If I don't respond before the timeout, the action expires and the agent moves on without executing.

In practice: agent wants to insert a batch of test records into staging. It pauses, shows me the INSERT statement with all values. I see it's 50 test orders, all marked as pending, all for the test account. I approve. Done.

If it had shown me DELETE FROM staging_orders WHERE status = 'pending' without a WHERE clause limiting it to test data, I would have rejected it. That's the circuit breaker.


The Approval Flow in Practice

Approval workflow — from agent action to push notification to phone approve/reject

It's not magic. It's a simple pause-and-show mechanism:

  1. Agent receives instruction: "Insert test data into orders for account test_acme."

  2. Agent plans the operation.

  3. Before execution, it hits the approval gate.

  4. I see a message: Awaiting approval for: INSERT INTO staging_orders (user_id, status, created_at) VALUES (123, 'pending', '2026-04-06'). 50 rows.

  5. I approve or reject.

  6. If approved, it executes. If rejected, it stops and logs why. If I ignore it, it expires.

No friction for normal operations. Friction exactly where you need it.


What I Actually Learned

The temptation is to blame OpenClaw. But that's not honest. OpenClaw worked exactly as designed. The agent did what it could do with the tools it had.

The real lesson: don't trust ambiguous instructions with unrestricted tools. Ever.

Whatever permission system you use—even just splitting your MCP configs into read-only and write versions—put something between your agent and your destructive tools. Make the agent ask first. Make it show its work.

Do that, and "clean up staging" stays a Thursday afternoon task. It doesn't become a war story.


Try Aerostack's approval gates: aerostack.dev


Part of the Agent Operations series. Start with the full guide: "I Run 5 MCP Servers on OpenClaw"


Related articles

Approving Agent Actions from Your Phone: The 5-Second Workflow

Your agent wants to git push origin main. Approve from your lock screen. The 5-second mobile workflow for agent approvals.

Navin Sharma
Navin Sharma
5m