What Happens When the Agent Does Something Wrong
Rollback for agent actions comes in three patterns, and your framework ships with none of them.
Every agent framework demo answers the question “what can the agent do.” Your CISO is going to ask a different one: what happens after it does the wrong thing. Not the wrong thing as in blocked by a guardrail. The wrong thing as in the action executed cleanly, the API returned a 200, and the outcome was wrong anyway. A refund issued to the wrong account. A customer record updated with a hallucinated value. An email that should never have gone out, sitting in an inbox you don’t control. The trace looks perfect. The damage is real. I’ve spent this week walking through the layers that govern agents before and during execution, and this is the post about the layer nobody builds: what you do after.
The recovery patterns that exist fall into three families, and the names come from distributed systems because that’s the only field that has taken this problem seriously. Soft cancellation, hard rollback, and compensation transactions. Each one answers the same question at a different point in the action’s lifecycle, and each one carries a cost that determines where it fits. Walk through them in order and you’ll notice something uncomfortable: the further down the list you go, the more damage has already happened by the time the pattern engages.
Soft cancellation is the pattern where the agent’s action is logged, staged, and held before it executes. The agent proposes the refund; the refund sits in a queue; a human or a policy engine approves it; then it runs. Strictly speaking this is not rollback at all. It’s delayed execution wearing a recovery costume, and that’s exactly why it works: the cheapest action to undo is the one that never happened. The cost is latency. A staged action can sit for minutes or hours waiting on approval, which rules the pattern out for anything interactive and rules it in for exactly the category where it belongs: low-frequency, high-stakes actions where a human should have been in the loop anyway. If you read the HITL post that opened this arc, this is where those conditional intervention gates live.
Hard rollback is the pattern most engineers assume they’ll use and almost none actually can. Constrain the agent to reversible actions only, snapshot the prior state before every write, and undo means restore. Inside a transaction boundary you own, your own Postgres, your own document store, this works and it’s cheap. The catch is that reversibility decays. The moment another system reads the value the agent wrote, restoring the prior state stops being an undo and starts being a second change that the downstream system never hears about. A rollback executed an hour after the fact isn’t a rollback. It’s a new write with a nostalgic value. Hard rollback is honest only within the blast radius you fully control, and the honest version of that radius is smaller than most architecture diagrams admit.
Compensation transactions are what’s left when the action can’t be unwound. The refund that already cleared gets a clawback transaction. The email that already sent gets a correction email, which is not an undo, it’s a mitigation, and the difference matters legally and reputationally. Compensation is the most mature of the three patterns because it’s the one distributed systems formalized decades ago as the saga pattern: every step in a workflow ships with a defined counter-step, and when the workflow fails partway through, the counter-steps run in reverse order. The pattern is honest about irreversibility in a way the other two aren’t. Some things cannot be undone. They can only be answered.
Now look at what the agent frameworks themselves offer against that taxonomy, because the audit here is short. LangGraph’s interrupt pattern, which I covered on Thursday, is the strongest option in open source, and it’s a prevention mechanism: pause before the node executes, wait for a human, resume. That’s soft cancellation, and it’s good soft cancellation, but it’s the only one of the three patterns any major framework implements natively. CrewAI, AutoGen, and the OpenAI Agents SDK all treat post-execution recovery as somebody else’s problem. Read the docs for any of them and search for the word “rollback.” The silence isn’t an oversight. It’s a scoping decision: frameworks own the reasoning loop, and what the reasoning loop did to your production database is outside the loop.
This is where the tooling conversation gets misleading, because tools for this do exist and they are genuinely production-grade. Temporal has been running compensation logic for microservice workflows for years; the server is at v1.31.2 as of July 8, with the Python SDK at 1.30.0, and it sits under workflow infrastructure at companies that process real money. Restate is the younger entrant, v1.7.2 as of early July with a 1.0.3 Python SDK that shipped four days ago, built around durable execution with the same saga primitives in a lighter operational footprint. If your question is “can I get battle-tested compensation infrastructure off the shelf,” the answer is yes. That’s not the question.
The question is what triggers the compensation, and this is where the distributed systems framing quietly stops fitting. Temporal and Restate were built for a world where failure announces itself. A service times out. A step throws. A node crashes mid-workflow. The system knows something went wrong because something went wrong in a way software can detect, and the saga unwinds automatically. An agent’s worst failures don’t announce themselves. The tool call succeeded. Every step returned cleanly. The workflow completed. The failure signal arrives later, from a human, when a customer calls or an analyst reviews the log or the numbers don’t reconcile at close. The trigger for agent rollback isn’t an exception handler. It’s a judgment, and judgments arrive on human time.
That single difference reshapes the whole design. If the trigger is human judgment arriving hours later, you need a revocation window: a defined period during which every agent action remains reversible or compensable by policy, the way a bank gives you sixty days to dispute a charge. You need an identity model for who is allowed to pull that trigger, because “undo the agent’s last action” is itself a privileged, auditable operation. Most of all, you need the compensation defined per tool rather than per workflow. Temporal wants you to define the saga when you write the workflow. An agent doesn’t have a workflow; it composes one at runtime from whatever tools it holds. The only place the undo logic can live is next to the tool itself.
That gives you the decision rule I’d apply: classify every tool by reversibility before the agent gets access, and let the class pick the pattern. Actions that are reversible inside a transaction boundary you own get hard rollback with prior-state snapshots. Actions reversible through a defined counter-action in someone else’s system get a compensation handler, written at the same time as the tool connector, not after the first incident. Actions with no counter-action at all get soft cancellation and a human gate, and no amount of downstream machinery substitutes for that gate. Three buckets, three patterns, decided at tool onboarding time. The classification takes an afternoon. Retrofitting it after an incident takes a quarter, and I’m not exaggerating the difference, because the retrofit happens under audit scrutiny with legal in the room.
The deliverable at the end of all this is embarrassingly unglamorous: a table with one row per tool and four columns, reversibility class, undo mechanism, revocation window, owner. No framework generates it. No vendor sells it. It’s the actual answer to the CISO’s question, and the teams that have it wrote it before they needed it. The agent will eventually do something wrong. That part isn’t a risk, it’s a schedule. What you decide now is whether that day produces an incident report or a compensation record, and the difference is whether you wrote the undo before you granted the tool.
If this was useful, forward it to one engineer who needs less noise in their feed.


