The action that fires twice
If the loop retries a step that already had a side effect, sending an email, charging a card, the action can fire again, because a retried tool call has no memory that the first one succeeded.
A transient timeout triggers a retry, and the customer is charged twice for the same order.
where_are_you
The maturity ladder, worst to best
These are the rungs the Agent Reliability Scorecard scores for this dimension, straight from the tool. Find where your agent sits, then aim for the top rung.
It would fire again: duplicate emails or double charges are possible
We mostly avoid retries, but there's no real guard
Critical actions check whether they already ran before acting
Side-effecting actions are idempotent by design (keys / dedup)target
why_it_matters
Agent loops retry. A tool call times out, a step is re-run after a recoverable error, the whole task restarts from a checkpoint, and any of these can replay an action that already happened. For a read that's harmless. For a side effect, an email, a payment, a provisioning call, a replay means a duplicate: two emails, a double charge, two resources created. The model has no idea the first call went through, because from its view the result never came back.
Assume the loop will retry, then make retries harmless. Give every external side-effecting action an idempotency key so a repeat is recognized and ignored, or a pre-check that asks whether the action already ran before doing it again. Idempotency is a property you design into the action, not something the agent framework gives you. Build it wherever a duplicate would be visible to a user or an account.
more_failure_modes
Related ways agents break
The agent that never stops
Read itTool-output integrityThe tool result that hijacks the agent
Read itSee all 7 failure modes, or score your loop with the scorecard.
faq
Questions & answers
- Why does my agent perform the same action twice?
- Because the loop retried a step and the action wasn't idempotent. A timeout, a recoverable error, or a checkpoint restart can replay a tool call, and a side effect like an email or a charge fires again since the call has no record that the first one succeeded. Add idempotency keys or pre-checks to side-effecting actions.
- How do you make an agent's side effects safe to retry?
- Give each external action an idempotency key the downstream system deduplicates on, or a pre-check that verifies whether the action already ran before repeating it. Assume retries will happen and design the action so a repeat is a no-op rather than a second charge or a second email.
Fixing one failure mode is a day. Hardening the whole loop is the work.
I review where your agent loop terminates, how it escalates, how it fences tool output, idempotency on the side effects, and the evals that catch a regression before users do. Book a call, or leave your email.
Prefer proof first? See how this plays out in real case studies →