{"record":{"id":"3d6b8997961c8403","repo":"can1357/oh-my-pi","slug":"empty-report-reportissuedeviceusage","errorCode":null,"errorMessage":"Empty report. ${reportIssueDeviceUsage()}","messagePattern":"Empty report\\. (.+?)","errorType":"validation","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/report-tool-issue.ts","lineNumber":81,"sourceCode":"\n/** Call preview for an `xd://report_issue` write. */\nexport function renderReportIssueDeviceCall(content: unknown, uiTheme: Theme): Component {\n\tconst body = typeof content === \"string\" ? replaceTabs(content.trim().split(\"\\n\")[0] ?? \"\") : \"\";\n\tconst text = renderStatusLine(\n\t\t{\n\t\t\ticon: \"pending\",\n\t\t\ttitle: \"Report Tool Issue\",\n\t\t\tdescription: body ? truncateToWidth(body, 72) : undefined,\n\t\t},\n\t\tuiTheme,\n\t);\n\treturn new Text(text, 0, 0);\n}\n\nfunction parseReportIssueBody(text: string): { tool: string; report: string } {\n\tconst body = text.trim();\n\tif (!body) {\n\t\tthrow new ToolError(`Empty report. ${reportIssueDeviceUsage()}`);\n\t}\n\tconst firstNewline = body.indexOf(\"\\n\");\n\tif (firstNewline >= 0) {\n\t\tconst tool = body.slice(0, firstNewline).trim();\n\t\tconst report = body.slice(firstNewline + 1).trim();\n\t\tif (tool && report) return { tool, report };\n\t}\n\tconst colon = body.indexOf(\":\");\n\tif (colon > 0) {\n\t\tconst tool = body.slice(0, colon).trim();\n\t\tconst report = body.slice(colon + 1).trim();\n\t\tif (tool && report) return { tool, report };\n\t}\n\tthrow new ToolError(`Invalid report format. ${reportIssueDeviceUsage()}`);\n}\n\n/**\n * Whether Auto-QA is active for this session.","sourceCodeStart":63,"sourceCodeEnd":99,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/report-tool-issue.ts#L63-L99","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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"],"exampleFix":"// before\nawait reportToolIssue(\"\");\n// after\nconst report = buildReport().trim();\nif (report) await reportToolIssue(`${toolName}\\n${report}`);","handlingStrategy":"validation","validationCode":"if (typeof body !== \"string\" || !body.trim()) { throw new Error(\"Report body must be a non-empty '<tool>\\\\n<report>' string\"); }","typeGuard":"function hasReportBody(v: unknown): v is string { return typeof v === \"string\" && v.trim().length > 0; }","tryCatchPattern":"try { await reportIssue(body); } catch (e) { if (e instanceof ToolError && e.message.startsWith(\"Empty report\")) { /* prompt user/model for report content */ } else throw e; }","preventionTips":["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"],"tags":["tool-input","validation","empty-input"],"backgroundTag":"empty-tool-input","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}