{"record":{"id":"69330a805f50ce56","repo":"can1357/oh-my-pi","slug":"report-cannot-be-empty","errorCode":null,"errorMessage":"Report cannot be empty.","messagePattern":"Report cannot be empty\\.","errorType":"validation","errorClass":"ToolError","httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/tools/checkpoint.ts","lineNumber":125,"sourceCode":"\n\tasync execute(\n\t\t_toolCallId: string,\n\t\tparams: RewindParams,\n\t\t_signal?: AbortSignal,\n\t\t_onUpdate?: AgentToolUpdateCallback<RewindToolDetails>,\n\t\t_context?: AgentToolContext,\n\t): Promise<AgentToolResult<RewindToolDetails>> {\n\t\tif (!this.session.getCheckpointState?.()) {\n\t\t\tif (this.session.getLastCompletedRewind?.()) {\n\t\t\t\tthrow new ToolError(\n\t\t\t\t\t\"Checkpoint already completed; continue from the retained rewind report instead of calling rewind again.\",\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new ToolError(\"No active checkpoint. Create a checkpoint before calling rewind.\");\n\t\t}\n\t\tconst report = params.report.trim();\n\t\tif (report.length === 0) {\n\t\t\tthrow new ToolError(\"Report cannot be empty.\");\n\t\t}\n\t\treturn toolResult<RewindToolDetails>({ report, rewound: true })\n\t\t\t.text([\"Rewind requested.\", \"Report captured for context replacement.\"].join(\"\\n\"))\n\t\t\t.done();\n\t}\n}\n","sourceCodeStart":107,"sourceCodeEnd":132,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/tools/checkpoint.ts#L107-L132","documentation":"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.","triggerScenarios":"Calling rewind with report=\"\", report=\"   \", or a params object where report is whitespace-only.","commonSituations":"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.","solutions":["Pass a non-empty, trimmed description of what should be restored/replaced in the rewind report.","Validate/fallback the report value at the call site before invoking the tool.","If the model produced an empty report, re-prompt it to summarize the rewind intent."],"exampleFix":"// before\nawait session.tools.rewind({ report: \"   \" });\n\n// after\nconst report = summarizeRewindIntent().trim();\nif (report.length > 0) {\n  await session.tools.rewind({ report });\n}","handlingStrategy":"validation","validationCode":"const report = (params.report ?? \"\").trim();\nif (report.length === 0) throw new Error(\"rewind requires a non-empty report\");","typeGuard":null,"tryCatchPattern":"try {\n  await rewindTool.execute(params, ...);\n} catch (err) {\n  if (err instanceof ToolError && err.message === \"Report cannot be empty.\") {\n    params.report = fallbackRewindSummary();\n    await rewindTool.execute(params, ...);\n  } else throw err;\n}","preventionTips":["Trim and validate tool arguments at the call site before invoking.","Constrain the model's schema so report is a required non-empty string.","Provide a deterministic fallback summary when the model omits content."],"tags":["validation","parameters","tool-error","empty-input"],"backgroundTag":"empty-required-parameter","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}