can1357/oh-my-pi · error · ToolError

Checkpoint already active.

Error message

Checkpoint already active.

What it means

The checkpoint tool allows only one active checkpoint per session. execute() checks session.getCheckpointState() and throws this ToolError if a checkpoint is already running — checkpoints are exclusive because they frame an exploration-to-findings workflow.

Source

Thrown at packages/coding-agent/src/tools/checkpoint.ts:80

	readonly intent = (args: Partial<CheckpointParams>) => (args.goal ? `checkpointing: ${args.goal}` : "checkpointing");

	constructor(private readonly session: ToolSession) {
		this.description = prompt.render(checkpointDescription);
	}

	static createIf(session: ToolSession): CheckpointTool | null {
		return new CheckpointTool(session);
	}

	async execute(
		_toolCallId: string,
		params: CheckpointParams,
		_signal?: AbortSignal,
		_onUpdate?: AgentToolUpdateCallback<CheckpointToolDetails>,
		_context?: AgentToolContext,
	): Promise<AgentToolResult<CheckpointToolDetails>> {
		if (this.session.getCheckpointState?.()) {
			throw new ToolError("Checkpoint already active.");
		}
		const startedAt = new Date().toISOString();
		return toolResult<CheckpointToolDetails>({ goal: params.goal, startedAt })
			.text([`Checkpoint: ${params.goal}`, "Finish exploration and formulate findings."].join("\n"))
			.done();
	}
}

export class RewindTool implements AgentTool<typeof rewindSchema, RewindToolDetails> {
	readonly name = "rewind";
	readonly approval = "read" as const;
	readonly label = "Rewind";
	readonly summary = "Rewind to a previously created checkpoint";
	readonly description: string;
	readonly parameters = rewindSchema;
	readonly strict = true;
	readonly loadMode = "discoverable";
	readonly intent = (): string => "rewinding";

View on GitHub (pinned to 9690622007)

Solutions

  1. Finish or clear the active checkpoint before starting a new one
  2. Check session.getCheckpointState() before calling the tool to see the existing goal/startedAt
  3. Reset the session (or its checkpoint state) if the prior checkpoint is orphaned from an aborted run
  4. Serialize checkpoint usage: one checkpoint per session at a time

Example fix

// before
await checkpointTool.execute({ goal: 'explore auth' }) // second call
// after
if (!session.getCheckpointState?.()) {
	await checkpointTool.execute({ goal: 'explore auth' });
}
Defensive patterns

Strategy: validation

Validate before calling

const state = session.getCheckpointState?.();
if (state) throw new Error(`checkpoint already active: ${state.goal}`);

Try / catch

try {
	await checkpointTool.execute({ goal }, ...);
} catch (err) {
	if (err instanceof ToolError && /already active/.test(err.message)) {
		// resolve or clear the existing checkpoint, then retry
	} else throw err;
}

Prevention

When it happens

Trigger: Calling checkpoint.start (or execute) while a previous checkpoint was started and never cleared; agent retrying the tool after a partial failure that left state set; two agents/subtasks sharing one session each starting a checkpoint.

Common situations: Workflow script that starts a checkpoint but aborts before finishing it; user manually re-running a checkpoint step in an interactive session; long-running checkpoint from a prior task still active when a new task begins.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/c9134529ae402912. Report an issue: GitHub.