Bounded agent tools
Timeout after the write, before the tool response
The hardest retry case is a successful mutation whose response never reaches the agent. Inject that failure deliberately and inspect the business record.
In this article
Put the fault in the right place
Use a test order and an operation that adds a delivery note. Arrange for the downstream service to commit the note, then drop or delay the response before the tool receives it. A timeout before the request reaches the service tests a much easier case.
Record the operation identifier and target version before starting. The test needs to correlate the original request, any retry and the final business record. Without that link, two identical notes could be mistaken for separate intended actions.
Keep the fixture isolated from real dispatch or notification integrations. The purpose is to observe duplicate prevention, not to create external work.
Observe how uncertainty is represented
The executor should distinguish an uncertain result from a definite rejection. If it knows only that the response was lost, it should not report that no change occurred. That false certainty often drives an automatic duplicate.
Inspect the agent's next step. Does it ask for operation status, retry with the same identifier or generate a new request? The safe choice depends on the downstream contract, but starting a fresh business operation without reconciliation is usually the behaviour this test should expose.
If idempotency is supported, verify its scope and retention. A retry with a different identifier or after the deduplication record expires may not receive the same protection.
Restart the process before recovery
After the timeout, stop the worker and resume from durable state. This removes any accidental protection supplied by in-memory variables. Confirm that the resumed run knows which operation is uncertain and does not infer success from a conversational sentence.
Then deliver a delayed response from the original call. The operation record should accept a compatible result without creating another mutation or moving a completed operation backwards into a pending state.
Run a concurrent retry as a separate case. Two workers can both decide to recover the same operation unless ownership or atomic state transitions prevent it.
Assert the final business effect
Check that the delivery note appears once and that the operation record identifies the committed target version. Count downstream calls separately from side effects. More than one network attempt may be acceptable under an idempotent contract, while more than one business effect is not.
Verify the user-facing message too. It should eventually reflect the recorded result and should not continue inviting the user to repeat a change already committed. Preserve the fault-injection point and assertions as a regression test whenever retry, queue or tool code changes.
Primary sources
AWS Builders' Library: idempotent APIsPostgreSQL: explicit lockingReferences checked 11 September 2026.