← Agent answers and comparisons
Practical guide · Agent action safety

How to Prevent an AI Agent From Performing the Same Action Twice

A practical idempotency pattern for preventing duplicate AI-agent refunds, orders, messages, and other consequential actions across retries and parallel runs.

Short answer

Give every consequential action a stable identity, acquire one atomic lock before execution, and mark the action complete afterward. The agent should execute only when the lock service returns safe_to_execute: true.

The failure this prevents

An agent submits a refund, loses the network response, and retries. A prompt instruction such as “do not retry” cannot prove whether the first request succeeded. The safety state must live outside the model and outside one short-lived process.

Recommended workflow

  1. Describe the action with a stable action name, scope, and identity-defining JSON arguments.
  2. Fingerprint and atomically lock that intent before calling the external system.
  3. Execute only when safe_to_execute is exactly true; treat every other result as blocked.
  4. Complete the lock with the returned key and lock_id after the external result is known.
  5. On an uncertain outcome, check and reconcile instead of inventing a new action identity.

Working starting point

curl https://api.scrubmytext.com/v1/actions/lock-intent \
  -H "Authorization: Bearer smt_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"action":"refund_order","scope":"production","arguments":{"order_id":"82731","amount_minor":72500}}'

Relevant product: LockMyAction · REST + MCP

Reproducible example

Two workers race to refund the same order

Worker A and Worker B receive the same refund job after a queue retry. Both use action refund_order, production scope, order 82731, and 72,500 minor currency units. The JSON key order may differ, but the identity-defining values do not.

Expected behavior
Both requests resolve to the same action fingerprint. Exactly one worker can acquire the live execution right; the other receives a blocked result. After the winner records completion, a delayed retry remains blocked by the completed-action record.
What it teaches
The useful property is not “the model remembered.” It is that competing processes consult one atomic state record before the side effect. Authorization and provider-native idempotency still remain separate layers.

Production verification checklist

  • Send equivalent arguments with a different JSON key order and confirm the fingerprint is unchanged.
  • Run two lock attempts concurrently and assert that only one returns safe_to_execute.
  • Simulate an unknown provider outcome and confirm the workflow reconciles instead of creating a new identity.

Decision rule

Proceed only when safe_to_execute is true. Reuse the same identity-defining arguments for retries. A fingerprint identifies an action; it does not authorize it or prove the external action succeeded.

Good fit

  • Retries could charge, refund, send, delete, publish, or provision twice.
  • More than one worker or agent may race to perform the same action.
  • The process may crash between an external side effect and receipt of its response.

Use another approach when

  • The operation is naturally read-only and harmless to repeat.
  • The external provider already supplies durable idempotency with the exact retention you require.
  • You need business authorization; add an approval or policy control rather than treating idempotency as permission.

Options compared

OptionStrengthImportant limitationBest fit
Prompt-only instructionEasy to addNo durable state; disappears on restartNever as the only duplicate-action control
In-process flagFast within one processFails across workers, restarts, and parallel runsSingle-process prototypes only
Provider idempotency keyClose to the actual side effectCoverage and retention vary by providerUse it whenever available
LockMyActionStable fingerprint plus external atomic stateCaller still owns authorization and outcome reconciliationCross-agent or cross-provider workflows

Implementation cautions

  • Do not generate a fresh key for a retry.
  • Do not mark complete before the external outcome is known.
  • Use completion retention long enough to cover realistic delayed retries.

Frequently asked questions

Is an action fingerprint the same as authorization?

No. It identifies equivalent action intent; it does not prove that the caller is allowed to execute it.

Should I still use a provider idempotency key?

Yes. Layer provider-native protection with an independent workflow lock when the action crosses agents, providers, or processes.

What if the result is unknown?

Keep the action blocked, inspect the current state, and reconcile the external outcome before retrying.

How this guidance was reviewed

The product behavior described here is checked against ScrubMyText's public OpenAPI contract and automated contract tests. The worked example is synthetic and contains no customer data. Recommendations separate verified product behavior from broader implementation judgment, and every limitation remains visible rather than being converted into a marketing claim.

Related decisions

Next step

Use the product page for exact limitations and access requirements, then copy the corresponding REST or MCP workflow.