{"record":{"id":"82a7e8e59acaa945","repo":"paperclipai/paperclip","slug":"invalid-semantic-result","errorCode":null,"errorMessage":"Invalid semantic result","messagePattern":"Invalid semantic result","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/paperclip-runner/src/drivers/opencode/opencode-server-driver.ts","lineNumber":891,"sourceCode":"    const turnId = this.#activeTurnId;\n    if (turnId === null)\n      throw new Error(\"OpenCode tool call is not bound to an active turn\");\n    this.#emit(\n      \"item.started\",\n      {\n        kind: \"dynamicToolCall\",\n        item: {\n          type: \"tool_call\",\n          id: call.callId,\n          name: tool,\n          arguments: call.arguments,\n        },\n      },\n      { turnId, itemId: call.callId },\n    );\n    if (tool === PRP_COMPLETION_TOOL_NAME || tool === PRP_BLOCK_TOOL_NAME) {\n      const validation = validatePrpStructuredRunResult(call.arguments);\n      if (!validation.ok) throw new Error(\"Invalid semantic result\");\n      if (\n        (tool === PRP_BLOCK_TOOL_NAME &&\n          validation.result.reportedWorkDisposition !== \"blocked\") ||\n        (tool === PRP_COMPLETION_TOOL_NAME &&\n          validation.result.reportedWorkDisposition === \"blocked\")\n      )\n        throw new Error(\n          \"Semantic result disposition does not match the terminal tool\",\n        );\n      if (\n        validation.result.completionClaim.contractRevision !==\n        this.#taskEnvelope.completionContract.revision\n      ) {\n        throw new Error(\n          \"Semantic result completion contract revision does not match\",\n        );\n      }\n      const fingerprint = canonicalJson(validation.result);","sourceCodeStart":873,"sourceCodeEnd":909,"githubUrl":"https://github.com/paperclipai/paperclip/blob/01ad8584922b5d85292b1723cae71fa0d9b07a19/packages/paperclip-runner/src/drivers/opencode/opencode-server-driver.ts#L873-L909","documentation":"When OpenCode invokes the Paperclip terminal tools (`prp_completion` / `prp_block`), the tool arguments must validate against the PRP structured run-result schema via `validatePrpStructuredRunResult`. Malformed arguments — missing fields, wrong types, invalid completion claim — throw this error, meaning the agent emitted a structurally invalid final result.","triggerScenarios":"The agent model calls the completion/block tool with arguments that fail `validatePrpStructuredRunResult`: e.g. omitting `completionClaim`, wrong `reportedWorkDisposition` type, malformed `contractRevision`, or truncated JSON produced by the model.","commonSituations":"Weaker/smaller models hallucinate the terminal-tool argument shape; a prompt/version change altered the expected result schema but the agent's system instructions still teach the old shape; the agent emits the tool call with prose-wrapped arguments.","solutions":["Inspect the tool `arguments` in the event stream (`item.started` for the dynamicToolCall) to see which schema field failed validation.","Re-prompt or retry the turn: instruct the agent to call the terminal tool with the exact schema from the task envelope's completion contract.","Ensure the driver's task envelope schema version matches the agent's instructions — a mismatch between PRP schema versions produces systematic validation failures.","Run the same `validatePrpStructuredRunResult` on your side before the agent sends, via prompt-side validation examples, to reduce malformed calls."],"exampleFix":"// before (agent arguments)\nprp_completion({ summary: \"done\" }) // missing completionClaim -> 'Invalid semantic result'\n\n// after\nprp_completion({\n  reportedWorkDisposition: \"completed\",\n  summary: \"done\",\n  completionClaim: { contractRevision: 2, /* ...required claim fields */ }\n})","handlingStrategy":"validation","validationCode":"const check = validatePrpStructuredRunResult(args);\nif (!check.ok) throw new Error('agent terminal arguments invalid: ' + check.error);","typeGuard":"function isValidSemanticResult(args) { return validatePrpStructuredRunResult(args).ok; }","tryCatchPattern":"try {\n  await session.dispatchTool({ tool, callId, arguments });\n} catch (e) {\n  if (e.message === 'Invalid semantic result') {\n    // re-prompt the agent with the exact completion-contract schema\n  } else throw e;\n}","preventionTips":["Keep agent instructions and PRP schema versions in lockstep.","Include the terminal-tool JSON schema in the task envelope prompt.","Retry the turn when the model emits a malformed terminal call.","Log `item.started` arguments to diagnose schema drift."],"tags":["validation","schema","opencode","semantic-result"],"backgroundTag":"schema-validation-failed","analyzedSha":"01ad8584922b5d85292b1723cae71fa0d9b07a19","analyzedAt":"2026-09-10T03:14:50.855Z","contentChangedAt":"2026-09-10T03:14:50.855Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}