One Timeout, Two Orders: How to Make AI Actions Safe to Retry

Illustrated infographic summarizing: One Timeout, Two Orders: Make AI Actions Safe to Retry

By Greg Nowak. Updated 25 September 2026.

An AI agent places an order. The supplier accepts it, but the response disappears during a network timeout. The agent sees an error and tries again. If the integration treats that retry as a new instruction, one purchase quietly becomes two.

The same failure pattern can duplicate invoices, CRM records, support tickets, emails and fulfilment jobs. It matters whenever software performs an action with a real financial, operational or customer-facing consequence. A timeout tells you only that the caller did not receive an answer in time—not whether the action happened.

Define the business effect before writing the retry policy

Backoff, jitter and attempt limits protect an overloaded service. They do not prevent duplicate business effects. That protection belongs in the contract for each tool or API operation.

Operation What a retry should do Required safeguard
Read product or account data Repeat after a temporary failure Backoff, jitter and an attempt limit
Create or update a record Return the original resource or result Stable key, request fingerprint and stored result
Place an order or send a message Never repeat an accepted action Provider-supported retry key and reconciliation
Receive a webhook Acknowledge an event already claimed Atomic event claim and idempotent worker
Start slow work Report the original job’s status Durable queue, job ID and status endpoint
Choose retry behaviour according to the business effect, not simply the HTTP method.

This classification is a useful design and procurement exercise. For every action exposed to an AI workflow, the product owner and delivery team should be able to say what counts as “the same action,” how long that identity survives and who resolves an uncertain outcome.

Give one business intention one stable key

Create an idempotency key when the workflow decides to perform an action, persist it before the first API call and reuse it for every attempt. Do not generate a new UUID inside the retry loop. That makes every attempt look unrelated and removes the protection.

The key should identify the intention, not contain sensitive business data. Store a hash of the material request alongside it. If the amount, recipient, product or destination changes, create a new intention and key. If an existing key arrives with a different request hash, reject it instead of guessing which version is correct.

Provider rules are not interchangeable. Stripe’s current API documentation says it saves the first status and response body for a key, including a 500, and checks later parameters against the original request. Keys may be removed after at least 24 hours. LINE’s Messaging API requires the retry key on the first attempt, returns 409 after an accepted request and retains the key for 24 hours. Your own ledger may need to remember the business intention much longer.

Make the action ledger durable and the claim atomic

A practical ledger records the key, operation, request hash, workflow ID, status, timestamps, attempt count, provider request ID and completed result. Keep it in a database, not process memory, and enforce uniqueness on the key.

CREATE UNIQUE INDEX action_ledger_key_uq
  ON action_ledger (idempotency_key);

INSERT INTO action_ledger
  (idempotency_key, operation, request_hash, status)
VALUES
  (:key, :operation, :request_hash, 'processing')
ON CONFLICT (idempotency_key) DO NOTHING;

If the insert succeeds, that worker owns the action. If it inserts nothing, read the existing row. Return its stored result when complete, report that the original action is still processing, or follow an explicit recovery path. A separate “check, then insert” sequence is unsafe because two workers can pass the check together. PostgreSQL documents ON CONFLICT as the database-level mechanism for handling the uniqueness conflict.

Store the first useful response or a stable resource identifier. “Already processed” leaves an agent with nowhere to go; returning the original order or ticket ID lets the workflow continue safely.

Design for the outcome you cannot prove

A local ledger cannot guarantee exactly-once execution against an unrelated external service. The worker may call the supplier successfully and crash before recording completion. After restart, your database knows the action began but not whether the supplier accepted it.

The strongest design sends the same key to a provider that implements idempotency. Otherwise, use a unique business reference that can be queried. If neither is available, move the action to an explicit outcome_unknown state, stop automatic retries and reconcile it through an API lookup or human review. For consequential actions, uncertainty is safer than an automated guess.

Queues improve resilience, but they do not remove duplicates

Webhook providers and message queues can deliver work more than once. Verify the webhook signature, atomically claim the event identity, enqueue the work and acknowledge promptly. The worker must still be idempotent.

Stripe’s webhook guidance recommends returning a successful response before complex processing, using an asynchronous queue and recording processed event IDs. It also warns that separate events can represent the same logical change, so some integrations must deduplicate with both the event type and affected object ID.

Test “success followed by silence”

The most revealing test is not a clean API error. Simulate the downstream service accepting an order and then dropping the response. Let the agent retry and confirm that only one business action exists.

  • Send simultaneous requests with the same key.
  • Reuse a key with changed material data and confirm it is rejected.
  • Crash after the external call but before the local completion update.
  • Retry beyond the provider’s key-retention window.
  • Deliver the same webhook twice and in the wrong order.
  • Trace the workflow, action key, attempt, provider request ID and final status together.

Start where duplication would hurt most

Inventory agent tools, scheduled jobs and webhooks. Prioritise payments, purchasing, outbound communication and irreversible updates. For each one, document who creates the key, where it is stored, what response is replayed, when retries stop and who owns reconciliation.

This is often a small integration project with a large risk-reduction payoff. Greg can help your team map the failure boundaries, review provider contracts and build a reusable pattern for stable keys, atomic claims, result replay and operational logging. If your current retry strategy relies on hope or manual clean-up, get in touch for a practical review.

Retries should repeat delivery attempts, not business decisions. Once that distinction is enforced, a timeout becomes an operational nuisance instead of a second order.

Related on GrN.dk

Need help with this kind of work?

Review your retry and idempotency design with Greg Get in touch with Greg.

Sources

Latest articles

A small Drupal fix can affect unrelated live settings. Review the full configuration import, resolve environment differences and rehearse deployment and recovery.

An ingredient change may mean a menu needs updating, even when the recipe’s modification date stays the same. Here is how AI can help with review and approval in WordPress.

Check whether AI crawlers can reach your service and product content. Compare response HTML with rendered pages, then identify practical CMS and rendering fixes.

Improve site search for customers who use everyday language. See where synonyms, semantic retrieval and behavioural signals help, while keeping product codes reliable.

Follow customer data through n8n, OpenAI and your CRM. Check who can access retained copies, what redaction hides and whether deletion works before scaling.

When checkout fails, your operations provider needs concrete evidence to work with. See how AI, dmesg and journalctl can gather the evidence into a useful incident ticket.

OpenAI’s hosted Evals platform is closing. Preserve your tests, validate replacement scoring and keep releases covered before the October and November 2026 deadlines.

Decide which AI-assisted pages to keep, improve, combine or remove. Check claims, page overlap and metadata, then put clear review controls into your CMS.

Use October to trial daily AI reorder recommendations before Black Friday. Get your Shopify data, lead times and budget in order before turning recommendations into purchases.

When an OpenAI request stalls, customers need an accurate status. Set sensible retry limits, preserve submissions, and make unresolved work visible.