{"record":{"id":"8c7d173f4230f5a3","repo":"paperclipai/paperclip","slug":"action-already-consumed","errorCode":"action_already_consumed","errorMessage":"Tool action request was already consumed","messagePattern":"Tool action request was already consumed","errorType":"http","errorClass":"ToolGatewayHttpError","httpStatus":409,"severity":"error","filePath":"server/src/services/tool-gateway.ts","lineNumber":7626,"sourceCode":"    if (!claimed) {\n      const settled = await waitForActionRequestExecution(actionRequest.id);\n      const [settledInvocation] = await db\n        .select()\n        .from(toolInvocations)\n        .where(eq(toolInvocations.id, invocation.id))\n        .limit(1);\n      if (settled?.status === \"executed\" && settledInvocation) {\n        return storedInvocationResult(settledInvocation);\n      }\n      if (settled?.status === \"failed\") {\n        throw new ToolGatewayHttpError(\n          502,\n          settledInvocation?.errorMessage ?? \"Approved tool action failed\",\n          settledInvocation?.errorCode ?? \"tool_execution_failed\",\n          { actionRequestId: actionRequest.id, invocationId: invocation.id },\n        );\n      }\n      throw new ToolGatewayHttpError(\n        409,\n        \"Tool action request was already consumed\",\n        \"action_already_consumed\",\n      );\n    }\n\n    // Terminal-issue expiry revokes pending/approved requests, but a claim that\n    // committed just before the issue closed slips past that revocation. Recheck\n    // the issue after winning the claim so a governed action never runs external\n    // side effects for an issue that is already done or cancelled.\n    const issue = await assertIssueOpenForApprovedAction({\n      claimed,\n      invocation,\n    });\n\n    const signedPayload = readSignedToolArgumentsPayload({\n      signedArguments: claimed.signedArguments,\n      invocationId: invocation.id,","sourceCodeStart":7608,"sourceCodeEnd":7644,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/server/src/services/tool-gateway.ts#L7608-L7644","documentation":"Idempotency guard in executeApprovedAgentInvocation: the compare-and-set from approved to executing matched no rows, meaning another executor already consumed this approval (or it was resolved otherwise) and the wait-for-settlement fallback also found it neither executed nor failed. The request was already consumed and cannot run twice.","triggerScenarios":"Thrown at server/src/services/tool-gateway.ts:4177 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["This action request was already consumed by a prior execution. Create a new approval request instead of reusing it."],"exampleFix":null,"handlingStrategy":"validation","validationCode":null,"typeGuard":null,"tryCatchPattern":null,"preventionTips":[],"tags":[],"backgroundTag":null,"analyzedSha":"3f1d897a7c018d76563a21c6e39c3c9b03933622","analyzedAt":"2026-09-18T08:03:59.046Z","contentChangedAt":"2026-09-18T08:03:59.046Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}