can1357/oh-my-pi · error · ToolError
Checkpoint already completed; continue from the retained rew
Error message
Checkpoint already completed; continue from the retained rewind report instead of calling rewind again.
What it means
The checkpoint rewind tool refuses to run a second rewind because a rewind has already been completed in this session: the checkpoint state was consumed and cleared, and only the final rewind report is retained. The library throws this instead of silently re-rewinding, because rewinding twice could clobber work done after the first rewind. The agent should use the already-captured rewind report (e.g. for context replacement) rather than invoking the tool again.
Source
Thrown at packages/coding-agent/src/tools/checkpoint.ts:117
constructor(private readonly session: ToolSession) {
this.description = prompt.render(rewindDescription);
}
static createIf(session: ToolSession): RewindTool | null {
return new RewindTool(session);
}
async execute(
_toolCallId: string,
params: RewindParams,
_signal?: AbortSignal,
_onUpdate?: AgentToolUpdateCallback<RewindToolDetails>,
_context?: AgentToolContext,
): Promise<AgentToolResult<RewindToolDetails>> {
if (!this.session.getCheckpointState?.()) {
if (this.session.getLastCompletedRewind?.()) {
throw new ToolError(
"Checkpoint already completed; continue from the retained rewind report instead of calling rewind again.",
);
}
throw new ToolError("No active checkpoint. Create a checkpoint before calling rewind.");
}
const report = params.report.trim();
if (report.length === 0) {
throw new ToolError("Report cannot be empty.");
}
return toolResult<RewindToolDetails>({ report, rewound: true })
.text(["Rewind requested.", "Report captured for context replacement."].join("\n"))
.done();
}
}
View on GitHub (pinned to 9690622007)
Solutions
- Do not call the rewind tool again; read the report from session.getLastCompletedRewind() and continue from it.
- If a real second rewind is needed, create a new checkpoint first, then call rewind.
- Clear the completed-rewind marker (or start a fresh session) before issuing a new rewind request.
Example fix
// before (agent tool loop)
await session.tools.rewind({ report: secondReport });
// after
const previous = session.getLastCompletedRewind?.();
if (previous && !session.getCheckpointState?.()) {
usePreviousReport(previous.report); // don't call rewind again
} else {
await session.tools.rewind({ report: secondReport });
} Defensive patterns
Strategy: validation
Validate before calling
if (!session.getCheckpointState?.() && session.getLastCompletedRewind?.()) {
// rewind already done — use the retained report, don't call rewind again
} Try / catch
try {
await rewindTool.execute(params, ...);
} catch (err) {
if (err instanceof ToolError && /already completed/.test(err.message)) {
const report = session.getLastCompletedRewind?.()?.report;
// continue from retained report
} else throw err;
} Prevention
- Track rewind completion in the agent's tool-call loop so repeat calls are suppressed.
- Check session.getCheckpointState() before scheduling any rewind.
- In prompts, instruct the model that rewind is single-shot per checkpoint.
When it happens
Trigger: Calling the rewind tool's execute() when session.getCheckpointState() returns falsy AND session.getLastCompletedRewind() returns truthy — i.e. a rewind already finished earlier in the same session and the tool is invoked again.
Common situations: An LLM agent retries the rewind tool call because it didn't register that the first call succeeded; a scripted workflow calls rewind twice expecting idempotence; session state was restored mid-run losing the live checkpoint but retaining the completed-rewind marker.
Related errors
- No active checkpoint. Create a checkpoint before calling rew
- No plan is awaiting approval — ${PROPOSE_DEVICE_PATH} only a
- No pending action to apply — ${RESOLVE_DEVICE_PATH} is only
- directory stack is empty
- No messages to continue from
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/f49d2cbe61a3d643.
Report an issue: GitHub.