---
title: Revert to Attempt
description: Restore the workspace to a previous task attempt's filesystem state via JJ.
---

Each successful task attempt captures the current [JJ](https://jj-vcs.github.io/jj/) change ID into `_smithers_attempts.jj_pointer`. `revert` restores the workspace to that state and discards any graph snapshots recorded after the attempt began, so the run's timeline rolls back to the point-in-time of that attempt.

<Note>API reference: [Time Travel](/reference/time-travel) lists every revert and time-travel export, its options, and links to source and tests.</Note>

```bash
bunx smithers-orchestrator revert workflow.tsx \
  --run-id RUN_ID --node-id NODE_ID [--attempt N=1] [--iteration N=0]
```

Revert restores files only; it doesn't alter JJ history. The restoration creates a new change on top of the current working copy.

## Requirements

- JJ in `PATH` (`brew install jj` or `cargo install jj-cli`)
- Workspace is a JJ repository (`jj git init` or `jj init`)
- The target attempt was completed when JJ was available (otherwise no pointer was captured)

## Programmatic

```ts
import { revertToAttempt, timeTravel } from "smithers-orchestrator";

const result = await revertToAttempt(adapter, {
  runId: "abc123",
  nodeId: "implement",
  attempt: 2,
  iteration: 0,
});
```

where `adapter` is the `SmithersDb` instance for the run's database.

`revertToAttempt` returns `{ success: false, error: string }` if the attempt is not found or has no recorded JJ pointer (it does not throw for these cases). Inspect the returned `result.success` boolean to detect failures. On success it returns `{ success: true, jjPointer: string }`.

```ts
type RevertOptions = {
  runId: string;
  nodeId: string;
  iteration: number;
  attempt: number;
  onProgress?: (event: SmithersEvent) => void;
};

type RevertResult = {
  success: boolean;
  error?: string;
  jjPointer?: string;
};

function revertToAttempt(adapter: SmithersDb, opts: RevertOptions): Promise<RevertResult>;
```

Use `timeTravel` when you want the higher-level reset flow: it can restore VCS, reset the target node, and reset dependent nodes after the selected attempt.

```ts
const reset = await timeTravel(adapter, {
  runId: "abc123",
  nodeId: "implement",
  attempt: 2,
  iteration: 0,
  resetDependents: true,
  restoreVcs: true,
});
```

```ts
type TimeTravelOptions = {
  runId: string;
  nodeId: string;
  iteration?: number;
  attempt?: number;
  resetDependents?: boolean;
  restoreVcs?: boolean;
  onProgress?: (event: SmithersEvent) => void;
};

type TimeTravelResult = {
  success: boolean;
  jjPointer?: string;
  vcsRestored: boolean;
  resetNodes: string[];
  error?: string;
};

function timeTravel(adapter: SmithersDb, opts: TimeTravelOptions): Promise<TimeTravelResult>;
```
