can1357/oh-my-pi · error · ToolError

Report cannot be empty.

Error message

Report cannot be empty.

What it means

The rewind tool validates its required 'report' parameter: after trimming, an empty string is rejected. The report is the description captured for context replacement after rewinding, so an empty value carries no information and is refused.

Source

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

	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

  1. Pass a non-empty, trimmed description of what should be restored/replaced in the rewind report.
  2. Validate/fallback the report value at the call site before invoking the tool.
  3. If the model produced an empty report, re-prompt it to summarize the rewind intent.

Example fix

// before
await session.tools.rewind({ report: "   " });

// after
const report = summarizeRewindIntent().trim();
if (report.length > 0) {
  await session.tools.rewind({ report });
}
Defensive patterns

Strategy: validation

Validate before calling

const report = (params.report ?? "").trim();
if (report.length === 0) throw new Error("rewind requires a non-empty report");

Try / catch

try {
  await rewindTool.execute(params, ...);
} catch (err) {
  if (err instanceof ToolError && err.message === "Report cannot be empty.") {
    params.report = fallbackRewindSummary();
    await rewindTool.execute(params, ...);
  } else throw err;
}

Prevention

When it happens

Trigger: Calling rewind with report="", report=" ", or a params object where report is whitespace-only.

Common situations: An LLM emits an empty report argument when it has nothing to summarize; a template or serializer drops the report field; a caller passes undefined coerced to empty string.

Related errors


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