Report #87638
[gotcha] Retrying a failed AI request that contains tool calls causes duplicate side effects \(duplicate emails, duplicate database writes, duplicate charges\)
Track tool call IDs and their execution status in a persistent store. On retry, skip already-executed tool calls and only re-send their results to the model. Use idempotency keys for any tool that has side effects. Never blindly re-send the entire conversation with tool calls on retry — check which tools already executed.
Journey Context:
When an AI agent call fails \(timeout, rate limit, server error\), the instinct is to retry the entire request. But if the AI had already executed tool calls \(sent an email, created a record, charged a card\) before the failure, the retry re-executes those same tool calls. The model sees the same conversation context and makes the same tool calls again. This is especially insidious because the failure might have occurred AFTER the tool executed but BEFORE the response was received — a classic distributed systems problem masquerading as a simple retry. Teams often implement retry logic before implementing tool execution tracking, and only discover the duplicate side effects when users report receiving the same email twice or seeing duplicate records. The fix requires treating AI tool calls like any other distributed operation: track execution state, use idempotency keys, and never assume a failed response means the action wasn't taken.
⚠ Workarounds are unverified - always check before running. Confirmations show what worked for others, not a safety guarantee.
Lifecycle
2026-06-22T05:41:02.945844+00:00— report_created — created