The first order can succeed while your AI assistant sees an error. What happens next decides whether recovery creates a second bill.

A timeout is not proof that nothing happened

Your AI assistant submits a supplier order. The supplier accepts it, but the connection drops before the confirmation reaches your system. The assistant sees an error, decides to be helpful and tries again. Two boxes arrive next week. The language model may have understood the request perfectly; the workflow still produced the wrong business result. This is why retry behaviour belongs in the purchasing conversation, not only in the developer's error log.

There are several different events hiding behind the word failure. A request can fail validation before it leaves your system. A remote service can reject it without changing anything. Alternatively, the remote service can complete the action and lose its response on the journey back. Only the first two situations establish that no external effect occurred. A network timeout usually establishes uncertainty, not failure. Treating those states as interchangeable creates the duplicate.

The October 2026 Packt Build with AI agent safety playbook makes the same practical distinction: write actions need durable duplicate protection, and uncertain outcomes need reconciliation before another attempt. Its named examples include customer emails and payment release. These are engineering examples, not evidence of how frequently UK businesses suffer duplicate transactions. No prevalence percentage is needed to understand the commercial exposure.

What this means in practice is simple. Ask your supplier to demonstrate an accepted order whose acknowledgement disappears. Do not accept a demonstration that merely disconnects the service before the order reaches it. The question is what happens after success becomes invisible. Your agent needs a recorded state equivalent to 'outcome unknown', an owner for resolving it and a safe way to discover what the receiving system actually did. A cheerful retry message is not that evidence.

A timeout means the outcome may be unknown, not that the action failed.

Give the business action an identity that survives a restart

The useful technical term is idempotency: repeating the same intended operation should not create an additional effect. Think of a numbered instruction rather than a numbered attempt. An approved refund has one operation identity even if the network needs three attempts to deliver it. A genuinely separate refund needs a different identity, even when the customer, amount and invoice happen to look similar. The distinction comes from the business process, not from the model's wording.

A stable operation identifier should be created by the workflow and stored before dispatch. Keep it when the process restarts, when a queue delivers the same message again and when a model generates another tool call for the same approved action. The October iTechGuides retry-safety guide describes stable keys, database safeguards and downstream propagation. A fresh random key on every attempt defeats the protection, while using only a customer identifier can accidentally suppress legitimate later work.

Stripe provides a concrete supplier contract rather than a general promise. Its idempotent-request documentation says keys can be up to 255 characters long. For API v1, keys may be removed after they are at least 24 hours old, and reuse after removal can create a new request. These are Stripe-specific details, not universal API rules. They show why a retry policy must account for the receiving provider's actual retention window.

The identifier must also remain tied to the approved details. If the amount, recipient or destination changes, the system should reject accidental reuse rather than pretending it is the same instruction. Keep personal information out of the key itself; an opaque reference can point to an appropriately protected record. Ask your implementer where that reference is saved and whether a restart can lose it. If the answer is 'the assistant remembers', you have not yet established durable duplicate protection.

Number the intended business action, not each attempt to carry it out.

Make the protection reach the system that changes the world

A local checklist cannot fully protect an external service. Your workflow can mark an email as pending, dispatch it and then crash before saving the delivery response. On restart, the local record still looks unfinished. If the email provider cannot recognise a repeated instruction, another send may produce another message. A database transaction inside your application does not magically include a supplier's API, a customer's inbox or a payment network.

This is the boundary described in Isabelle Dubuis' October discussion of resumed agents. It separates message-level tool-call identifiers from durable business operation identifiers and explains the crash window between remote completion and local confirmation. The article cites a reported Agno issue as an example, not a representative failure rate. Its important lesson is that replay protection has to survive the handover between components.

Start with existing provider capabilities rather than commissioning a new framework. Check whether your CRM, payment processor or order service accepts a duplicate-protection key, what it considers the same request, how concurrent attempts behave and how long the protection lasts. Use those supported mechanisms where available. Your orchestration platform may offer retries or checkpoints, but those features need explicit configuration and do not establish that every connected tool is safe to repeat.

Where a provider lacks duplicate protection, a reliable business reference and status lookup may allow reconciliation. However, a quick search that finds nothing is not always proof of absence: records may appear late, or the search endpoint may be incomplete. Agree how long to wait, which status is authoritative and when a person must resolve the uncertainty. For an irreversible or expensive action, refusing to repeat an uncertain instruction can be the correct automated outcome. Reliability includes knowing when automatic recovery cannot make a trustworthy decision.

A local success log is not an end-to-end guarantee across several services.

Do not confuse approval, cancellation and duplicate protection

The obvious counterargument is that a person already approves important actions. Surely that stops the problem? It stops some wrong first actions, but approval and repetition are separate questions. A person can correctly approve one refund while the software issues it twice. Equally, a perfectly deduplicated payment can still go to the wrong recipient. You need the right action, appropriate permission and controlled execution; none of those replaces the others.

Approval should attach to the exact intended instruction, including the relevant amount, destination and scope. Retrying that instruction should preserve its identity rather than manufacture another approval or another transaction. If the details change, route the change through the appropriate decision. Do not let an agent reinterpret 'try again' as permission to create a second business action simply because the original attempt remains unresolved. That ambiguity needs a process rule outside the conversational exchange.

Cancellation is different again. A stop instruction prevents further work where the system can enforce it; it does not prove that an earlier external effect never happened. Our guide to AI agent cancellation across downstream work addresses that related boundary. Retry safety concerns what may happen when work resumes or repeats. A duplicate check, a cancellation check and a permission check can all be necessary for the same operation.

For UK organisations, record quality matters too. The ICO accuracy guidance says organisations should take reasonable steps to keep personal data accurate and make its source and status clear. The guidance is under review following the Data (Use and Access) Act, so check current advice for your use case. It does not prescribe idempotency keys. The practical connection is narrower: a duplicate account action should not leave misleading customer records, and a correction should clearly explain the sequence rather than quietly hiding what happened.

Approving one action is not approving the same action twice.

Test the awkward recovery path before granting more autonomy

A happy-path demonstration tells you whether an assistant can complete work under favourable conditions. Your acceptance test should also ask whether recovery creates extra work. Choose one low-risk workflow and list its external effects: the CRM record, supplier request, confirmation email and internal task. Give each intended effect a stable reference, then agree what evidence would establish that it happened once. Counting model responses is not a substitute for checking the destination systems.

For a purchasing example, simulate a lost acknowledgement after the supplier has accepted the order. Resume the workflow and inspect the supplier's records. Then restart the worker after dispatch but before the local success record is saved. Deliver the same queued instruction concurrently to two workers. Repeat an instruction after the provider's duplicate-protection window has elapsed. Finally, attempt to reuse an operation identifier with a different amount. These are proposed acceptance scenarios, not claims that a particular product already passes them.

What this means in practice is a short evidence pack your operations manager can read. For each scenario, record the intended action, the attempts, the authoritative external result and whether manual reconciliation was needed. An acceptable outcome may be one confirmed action, a safely rejected changed request or an unresolved case assigned to a named person. An unexplained extra order is a failure even if every individual API call returned a technically valid response.

Keep the pilot proportional. A duplicate draft note is different from a duplicate direct customer message or a second payment instruction. Prioritise the effects with the highest financial, confidentiality or relationship cost. Do not put live customers through a failure drill when a sandbox or controlled test account can establish the behaviour. Once the checks pass, keep monitoring duplicate attempts, unresolved outcomes and resolution time separately. A low error rate can conceal unresolved cases if the system labels uncertainty as success.

Test the missing acknowledgement after success, not only the outage before it.

Buy a recovery promise that names its limits

When commissioning an AI workflow, ask for the recovery behaviour in ordinary business language. Which actions are safe to repeat automatically? Which require a status check? Which stop for a person? How does the system distinguish a retry from a new customer request? Who owns an outcome that remains unknown overnight? A supplier should be able to answer without making you inspect implementation code. Technical detail can support the promise, but it cannot replace the operational commitment.

Be wary of unqualified 'exactly once' claims across multiple independent services. A local database can provide strong guarantees within its own transaction boundary. A remote service can offer documented duplicate handling. Together they can make a workflow much safer, but the overall claim still depends on those contracts, retention periods and failure paths. The useful promise is explicit and testable: the same approved operation uses a stable reference, uncertainty is visible, and unsupported retries are blocked or escalated.

Also ask about correction. Preventing duplicates does not make the first action correct, and undo is not always available. A correction email cannot remove an earlier message from someone's inbox. Cancelling an order may be impossible after dispatch. Refunding an accidental charge is another authorised financial action, not a reason for an assistant to improvise. Agree the available correction, who approves it and what customers will be told before granting the workflow more authority.

Your first step need not be a large engineering project. Take one existing automation that writes to a business system and ask its owner to trace an instruction through a timeout and restart. Use supported provider features and your current platform's durable workflow tools before considering custom infrastructure. Record any gap as a bounded improvement with an acceptance test. The outcome you want is not an agent that tries harder indefinitely. It is an operation you can trust to finish once, report uncertainty honestly and involve the right person when completion cannot be established.

A trustworthy recovery promise says where automation must stop.

Key Takeaways

  • Assign one durable operation identity to each intended external action, and preserve it across retries and restarts.
  • Check the receiving provider's duplicate-protection contract, including retention periods and changed-parameter handling.
  • Treat a post-dispatch timeout as an unknown outcome until authoritative evidence resolves it.
  • Test lost acknowledgements, restarts, concurrent delivery and expired protection windows before increasing autonomy.
  • Name the person responsible for uncertain outcomes and approve correction paths separately.