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
- Provide a non-empty body whose first line is the tool name and remaining lines are the report text
- Check the input variable actually holds report text before calling (log/inspect it)
- 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
- Always build the body as toolName + newline + report text
- Assert the report variable is a non-empty string before calling
- Skip the tool call entirely when there is nothing to report
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
- Managed skill "${name}" needs a non-empty description.
- Managed skill "${name}" needs a non-empty body.
- objective is required when op=create
- token_budget must be a positive integer when provided
- `pat` must be a non-empty pattern
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/3d6b8997961c8403.
Report an issue: GitHub.