{"record":{"id":"8af41e8f76de33db","repo":"paperclipai/paperclip","slug":"action-tool-mismatch","errorCode":"action_tool_mismatch","errorMessage":"Approved action request is for a different tool","messagePattern":"Approved action request is for a different tool","errorType":"http","errorClass":"ToolGatewayHttpError","httpStatus":409,"severity":"error","filePath":"server/src/services/tool-gateway.ts","lineNumber":7820,"sourceCode":"        invocationId: invocation.id,\n        toolName: invocation.toolName,\n        ownsExecutingClaim: true,\n      });\n    }\n\n    const argumentsSummary = validateToolContent({\n      value: parameters,\n      direction: \"arguments\",\n      sensitiveMode: \"redact\",\n      promptInjectionMode: \"ignore\",\n    }).summary;\n    // Final recheck at the last DB write before dispatch: tool and snapshot\n    // resolution above involve network calls, so re-verify the issue is still\n    // open now that only the provider call remains. A close that commits after\n    // this read has raced an execution that was approved, claimed, and verified\n    // while the issue was open; that instant is irreducible for an external\n    // side effect gated by DB state (holding a DB lock across a remote provider\n    // call is not an option), and the accepted linearization is that the\n    // execution wins — its result still lands on the expired card via\n    // reflectToolActionInteractionLifecycle.\n    await assertIssueOpenForApprovedAction({ claimed, invocation });\n\n    const startedAt = Date.now();\n    await db\n      .update(toolInvocations)\n      .set({\n        status: \"executing\",\n        approvalState: \"approved\",\n        startedAt: new Date(),\n        updatedAt: new Date(),\n      })\n      .where(eq(toolInvocations.id, invocation.id));\n    await reflectToolActionInteractionLifecycle({\n      actionRequestId: claimed.id,\n      status: \"executing\",\n    });","sourceCodeStart":7802,"sourceCodeEnd":7838,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/server/src/services/tool-gateway.ts#L7802-L7838","documentation":"Replay consistency guard: the tool name on the stored invocation does not equal the tool the session is currently calling. The 409 action_tool_mismatch prevents replaying an approval granted for one tool against a different tool within the same session context.","triggerScenarios":"Thrown at server/src/services/tool-gateway.ts:5576 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["Execute the approved action with the same tool it was approved for; tool substitution invalidates the approval."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-08-18T22:49:45.177Z","contentChangedAt":"2026-08-18T22:49:45.177Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}