paperclipai/paperclip · error · ToolGatewayHttpError
action_tool_mismatch
action_tool_mismatch
Error message
Approved action request is for a different tool
What it means
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.
Solutions
- Execute the approved action with the same tool it was approved for; tool substitution invalidates the approval.
Defensive patterns
Strategy: validation
When it happens
Trigger: Thrown at server/src/services/tool-gateway.ts:5576 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of paperclipai/paperclip@3f1d897a7c (2026-08-18).
Data as JSON: /api/errors/8af41e8f76de33db.
Report an issue: GitHub.
Appendix: source
Thrown at server/src/services/tool-gateway.ts:7820
invocationId: invocation.id,
toolName: invocation.toolName,
ownsExecutingClaim: true,
});
}
const argumentsSummary = validateToolContent({
value: parameters,
direction: "arguments",
sensitiveMode: "redact",
promptInjectionMode: "ignore",
}).summary;
// Final recheck at the last DB write before dispatch: tool and snapshot
// resolution above involve network calls, so re-verify the issue is still
// open now that only the provider call remains. A close that commits after
// this read has raced an execution that was approved, claimed, and verified
// while the issue was open; that instant is irreducible for an external
// side effect gated by DB state (holding a DB lock across a remote provider
// call is not an option), and the accepted linearization is that the
// execution wins — its result still lands on the expired card via
// reflectToolActionInteractionLifecycle.
await assertIssueOpenForApprovedAction({ claimed, invocation });
const startedAt = Date.now();
await db
.update(toolInvocations)
.set({
status: "executing",
approvalState: "approved",
startedAt: new Date(),
updatedAt: new Date(),
})
.where(eq(toolInvocations.id, invocation.id));
await reflectToolActionInteractionLifecycle({
actionRequestId: claimed.id,
status: "executing",
});View on GitHub (pinned to 3f1d897a7c)