can1357/oh-my-pi · error · ToolError

Empty report. ${reportIssueDeviceUsage()}

Error message

Empty report. ${reportIssueDeviceUsage()}

What it means

parseReportIssueBody parses the body of a tool-report submission, which must be '<tool-name>\n<report text>' (or '<tool-name>: <report text>'). It throws this ToolError when the entire body is empty or whitespace-only, because there is nothing to parse. reportIssueDeviceUsage() appends usage instructions so the model/caller can retry with the right shape.

Source

Thrown at packages/coding-agent/src/tools/report-tool-issue.ts:81

/** Call preview for an `xd://report_issue` write. */
export function renderReportIssueDeviceCall(content: unknown, uiTheme: Theme): Component {
	const body = typeof content === "string" ? replaceTabs(content.trim().split("\n")[0] ?? "") : "";
	const text = renderStatusLine(
		{
			icon: "pending",
			title: "Report Tool Issue",
			description: body ? truncateToWidth(body, 72) : undefined,
		},
		uiTheme,
	);
	return new Text(text, 0, 0);
}

function parseReportIssueBody(text: string): { tool: string; report: string } {
	const body = text.trim();
	if (!body) {
		throw new ToolError(`Empty report. ${reportIssueDeviceUsage()}`);
	}
	const firstNewline = body.indexOf("\n");
	if (firstNewline >= 0) {
		const tool = body.slice(0, firstNewline).trim();
		const report = body.slice(firstNewline + 1).trim();
		if (tool && report) return { tool, report };
	}
	const colon = body.indexOf(":");
	if (colon > 0) {
		const tool = body.slice(0, colon).trim();
		const report = body.slice(colon + 1).trim();
		if (tool && report) return { tool, report };
	}
	throw new ToolError(`Invalid report format. ${reportIssueDeviceUsage()}`);
}

/**
 * Whether Auto-QA is active for this session.

View on GitHub (pinned to 9690622007)

Solutions

  1. Provide a non-empty body whose first line is the tool name and remaining lines are the report text
  2. Check the input variable actually holds report text before calling (log/inspect it)
  3. If a report is genuinely empty, skip calling the tool rather than sending a placeholder

Example fix

// before
await reportToolIssue("");
// after
const report = buildReport().trim();
if (report) await reportToolIssue(`${toolName}\n${report}`);
Defensive patterns

Strategy: validation

Validate before calling

if (typeof body !== "string" || !body.trim()) { throw new Error("Report body must be a non-empty '<tool>\\n<report>' string"); }

Type guard

function hasReportBody(v: unknown): v is string { return typeof v === "string" && v.trim().length > 0; }

Try / catch

try { await reportIssue(body); } catch (e) { if (e instanceof ToolError && e.message.startsWith("Empty report")) { /* prompt user/model for report content */ } else throw e; }

Prevention

When it happens

Trigger: Calling the report-tool-issue tool with body = "", " ", or a body consisting only of newlines; programmatically invoking the tool after the report text was trimmed away (e.g. a variable that was undefined interpolated as empty).

Common situations: An LLM calls the tool with an empty arguments object or only whitespace; a script forwards an empty clipboard/file content; a template produces an empty report field.

Related errors


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