Skip to main content
Run anvil replay <traceId> to re-execute a previously captured agent trace entirely from recorded data. Anvil reads the trace from a SQLite trace store, reconstructs the agent’s original inputs, and drives the agent loop using a ReplayDriver that feeds back the recorded model responses in order. Tool functions are also replaced with stubs that return their recorded outputs, so no real side effects — database writes, external API calls, emails — are re-fired. Use replay to reproduce a production failure on your laptop, step through an edge case, or verify that a code fix changes the agent’s behaviour as expected.

Usage

anvil replay <traceId> [options]
<traceId> is the ID of the trace to replay. You can find trace IDs in the Anvil dashboard, your trace store, or in logs emitted by a traced agent route.

Flags

<traceId>
string
Required. The identifier of the trace to replay. Anvil looks this up in the SQLite store specified by --store.
-s, --store <file>
string
default:".anvil/traces.db"
Path to the SQLite trace database written by SqliteTraceStore. If the file does not exist or cannot be opened, anvil replay prints an error and exits with code 1.

How replay works

1

Load the trace

Anvil opens the SQLite store and fetches the full trace by ID. The trace includes every span: the top-level agent span, each model call span (with the recorded response text and tool calls), and each tool span (with the recorded output).
2

Build a ReplayDriver

The ReplayDriver (from anvil/agent) is initialised with the recorded model responses in chronological order. Each call to generate() or stream() pops the next response off the queue instead of making a live API request. Cost and token usage are reported as zero for replayed responses.
3

Stub tool functions

Each tool that appeared in the original trace is replaced with a stub that returns its recorded output in call order. The original tool implementation is never invoked, so no writes, notifications, or API calls happen.
4

Run the agent loop

Anvil runs the full agent loop — the same loop used in production — but entirely against the mocked driver and stub tools. Events are streamed and printed as they occur.

Example

anvil replay abc-123
[anvil] replaying chat-agent (abc-123) — mocked model, no live calls

— iteration 1
tool_call: get_weather({"city":"Paris"})
tool_result: get_weather → {"temp":18,"condition":"cloudy"}
assistant: The weather in Paris is 18 °C and cloudy.

[anvil] replay complete (1 iteration(s))

Example: custom trace store

anvil replay abc-123 --store data/production-traces.db

ReplayDriver from anvil/agent

If you need to embed replay into your own scripts or tests, import ReplayDriver directly:
import { ReplayDriver, buildReplayFromTrace, replayToResult } from 'anvil/agent';
import { SqliteTraceStore } from 'anvil/trace';

const store = await SqliteTraceStore.open('.anvil/traces.db');
const trace = await store.getTrace('abc-123');

// High-level: replay to completion and get all events
const { events, result } = await replayToResult(trace);

// Low-level: build the replayable config and drive it yourself
const replayable = buildReplayFromTrace(trace);
// replayable.client uses a ReplayDriver under the hood
buildReplayFromTrace reconstructs the original agent inputs (messages, system prompt, model identifier) and wires up a ReplayDriver and stub tools. You can then pass the result to streamAgent for fine-grained event inspection.

Error: trace not found

[anvil] no trace "abc-123" in .anvil/traces.db
This happens when the trace ID does not exist in the store, or when you are pointing at the wrong store file. Double-check the trace ID from your dashboard or logs, and confirm the --store path matches the file written by your application’s tracer.
Side-effect tools are never re-invoked during replay. Stub implementations return the recorded output directly. If a tool’s recorded output queue is exhausted (the tool was called more times than recorded), the stub returns a sentinel string rather than throwing, so the replay completes.
Replay is most effective when your application uses SqliteTraceStore in production (or staging). Attach it to your agent routes during development and the trace DB will accumulate cases you can replay at any time without re-running the real workload.