TuskPointGitHub

Guides

Rollback

rollback_to is a durable undo. It restores the state of an earlier checkpoint as the new head of the same thread, so the agent continues from a known-good moment, without erasing the steps in between.

Why rollback?

Sometimes an agent walks itself into a bad state: a wrong tool result, a derailed plan, a corrupted intermediate. You want to go back to the last good checkpoint and continue from there. Rollback does exactly that, and because it stays on the same thread, the next resume picks up the restored state automatically.

How it works

Rollback reads the exact state at checkpoint_id and writes it back as a brand-new checkpoint at the head of the thread, parented off the previous head. The new head records rolled_back_from so the move is a visible, auditable step in the chain: the history reads ... bad state -> (rollback) -> restored good state.

Append-only by design

Rollback never deletes the checkpoints it skips over. They stay on the thread, so the verifiable trail is intact and the rollback itself shows up as a step you can audit. The undo is durable and stays on the record.

Rollback vs. fork

Both start from an earlier checkpoint, but they go opposite directions. fork branches that state into a new thread and leaves the original untouched, good for exploring an alternative path side by side. rollback_to stays on the same thread and makes the restored state the new head, good for "continue from here, the last bit was wrong."

Via the MCP tool

Any connected agent can roll a thread back with one call:

checkpoint_rollback
checkpoint_rollback(
  thread_id="run-42",
  checkpoint_id="0c3b84d1-…",
)

It returns the new head and what it restored:

returns
{
  "thread_id": "run-42",
  "checkpoint_id": "8a91f0c2-…",
  "restored_from": "0c3b84d1-…",
  "blob_id": "WL4TgZgqRE9Pwq1UEclzBJu89KFaaLe75p004_9gJyw",
  "rolled_back_from": "0c3b84d1-…"
}

Via the Python API

python
from langgraph_checkpoint_walrus import WalrusSaver, WalrusClient

saver = WalrusSaver(WalrusClient())
result = saver.rollback_to(
    thread_id="run-42",
    checkpoint_id="0c3b84d1-…",
)
print(result["restored_from"])  # 0c3b84d1-…

# The thread's head is now the restored state, resume continues from it.

The checkpoint must exist on the thread

Rolling back to a checkpoint_id that isn't in the thread raises a clear error. The target is always an earlier checkpoint of the same thread.