{"record":{"id":"cdf29000ab530468","repo":"paperclipai/paperclip","slug":"approved-tool-target-changed","errorCode":"approved_tool_target_changed","errorMessage":"Tool definition or connection changed; request a new review","messagePattern":"Tool definition or connection changed; request a new review","errorType":"http","errorClass":"ToolGatewayHttpError","httpStatus":409,"severity":"error","filePath":"server/src/services/tool-gateway.ts","lineNumber":9460,"sourceCode":"          agentId: invocation.agentId,\n          runId: invocation.runId,\n          issueId: issue.id,\n          projectId: issue.projectId,\n          createdAt: new Date(),\n          expiresAt: new Date(Date.now() + DEFAULT_SESSION_TTL_MS),\n        };\n        await restoreApprovedActionIdentity(\n          session,\n          signedPayload.identityContextId,\n        );\n        const tool = await findToolForSession(session, invocation.toolName);\n        if (\n          !approvalSnapshotsMatch(\n            signedPayload.approvalSnapshot,\n            await connectedRemoteApprovalSnapshot(session, tool),\n          )\n        )\n          throw new ToolGatewayHttpError(\n            409,\n            \"Tool definition or connection changed; request a new review\",\n            \"approved_tool_target_changed\",\n          );\n        const access = await policyService.decide(\n          policyInputForTool({\n            session,\n            tool,\n            parameters: signedPayload.arguments,\n          }),\n        );\n        if (!access.allowed && access.decision !== \"require_approval\")\n          throw new ToolGatewayHttpError(\n            403,\n            access.explanation,\n            access.reasonCode,\n          );\n      }","sourceCodeStart":9442,"sourceCodeEnd":9478,"githubUrl":"https://github.com/paperclipai/paperclip/blob/3f1d897a7c018d76563a21c6e39c3c9b03933622/server/src/services/tool-gateway.ts#L9442-L9478","documentation":"Post-approval integrity check: the signed payload decoded but the target it names (tool/invocation identity) differs from what the stored invocation now references, meaning the review target changed after the board reviewed it. Execution is refused with 409 so a modified action never runs under a stale approval.","triggerScenarios":"Thrown at server/src/services/tool-gateway.ts:5675 when the library encounters an invalid state.","commonSituations":"See trigger scenarios.","solutions":["The tool/target changed after review. Re-submit for approval with the final target; never alter an approved action's target."],"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"}