
Retry keys must follow the intended action
In short: An idempotency key should follow one authorised action across retries, preserving intent without collapsing separate requests into duplicates.
RFC 9110, published in June 2022, distinguishes idempotent HTTP methods from operations that cannot safely be repeated by default. An agent's retry loop does not erase that distinction simply because the first response timed out.
Retry keys must follow the intended action. My rule is to assign one durable identity to a user-authorised operation and reuse it while recovering that operation. A new model attempt is not necessarily a new instruction, and an identical request body is not necessarily the same instruction either.
Why a timeout leaves two plausible histories
The server may have performed the action and lost the response. Or it may never have received the request. From the client's timeout alone, both histories can look the same.
The AWS Builders' Library discussion of idempotent APIs explains why a caller-provided request identifier helps express intent. It also discusses the ambiguity of inferring duplicates from matching parameters: a caller may genuinely want two identical resources.
That is the operational problem to solve. A wrapper that generates a fresh key on every network retry labels the same intent as new work. A wrapper that hashes only the payload can collapse two legitimate intentions into one.
Attach the key before dispatch
For a hypothetical agent tool, I would create and persist the operation identity before sending the request. The operation record would bind the initiating user, the intended action, the relevant input fingerprint and the service's returned identity when available.
A retry would load that record. It would not ask the model to remember a token from its previous reasoning. Model context is a useful workspace, but an operation identity that prevents duplicate side effects belongs in durable application state.
If the user changes the requested action, the caller must decide whether that is a revision, cancellation or new operation. Reusing an old key with changed parameters is not a general update mechanism. The service's documented behaviour for mismatched parameters is part of the integration contract.
Export and delivery are separate actions
Imagine an assistant preparing an export and then submitting a delivery request to another service. I would give the export and the delivery separate operation identities. Retrying export generation should not automatically resend an already accepted delivery.
After an uncertain send response, the next step would reconcile the delivery identity or reuse its supported idempotency key. If the destination does not offer either capability, the honest state may remain unknown until another check resolves it. That is less convenient than a green tick, but it avoids inventing certainty.
This is a proposed design, not an experiment against a messaging provider. The same reasoning applies to a payment or resource-creation tool, but each service has its own key scope, retention period and error semantics. A key that the service has forgotten cannot offer indefinite duplicate protection.
Test the ambiguity, not only the happy retry
The HTTP semantics specification cautions against automatically retrying non-idempotent requests without knowledge that repetition is safe or the original was not applied. Build fixtures that make those facts explicit.
I would test a lost response after acceptance, a duplicated request before completion, a changed payload with the same identity and a deliberately repeated user instruction with a new identity. The last fixture matters: duplicate prevention must not prevent a user from doing the same legitimate thing twice.
What's in it for you
- Persist intent identity before the request can produce a side effect.
- Make unknown outcome and confirmed failure different recovery states.
Retry the same intention under the same contract; do not let each attempt invent a new action.


