This guide was prepared with AI assistance using the linked documentation. Code examples are illustrative; verify them against your environment and current API documentation before use.
A timeout is not proof of failure
An agent submits a request to create a record. The network times out before the response arrives. Did the server create it? If the agent simply tries again, it might create a duplicate.
Design the action to survive an uncertain response before adding automatic retries. Read-only lookups and external writes need different recovery rules.
Classify the failure first
A temporary rate limit or overloaded service may be retryable. Invalid input, denied permission, a content refusal, exhausted credits, and an enforced spend limit need different handling. Inspect the error code as well as the HTTP status.
OpenAI's error guide says a Retry-After value, when present for relevant transient errors, is a minimum wait. The SDK may also retry eligible failures, so account for its configuration before adding another retry loop.
Give each intended write a stable identity
Create an idempotency key for a user's intended action and persist it with the action state. Reuse that key if the same action must be retried. A new user-approved action needs a new key; do not derive permission from the key itself.
This is a local state sketch, not a payment or production implementation. The operation and its outcome need durable storage and an atomic uniqueness constraint in a real application.
type ActionState = "pending" | "succeeded" | "failed" | "unknown";
type ActionRecord = { key: string; state: ActionState; resultId?: string };
// Persist with a unique key; reconcile "unknown" before retrying a write.Reconcile uncertain outcomes
If the action provider offers a way to look up a request by its idempotency key or external ID, check that result before repeating the action. If the outcome cannot be determined, mark it as unknown and route it to an operator rather than presenting success or failure as fact.
Preserve the original approved arguments and record whether the operation was attempted. A retry must not silently expand the action or target a different recipient.
Set a retry budget
Use bounded attempts, a deadline, and backoff appropriate to the error. Respect the provider's Retry-After instruction where applicable. Stop retrying when a user cancels, authorization expires, or the failure requires a human or configuration change.
Streaming adds another complication: once output has reached the user, automatically replaying the entire request may duplicate text or actions. Track what was emitted and use the provider's documented recovery path.
Test duplicate and delayed events
Run synthetic tests for a duplicate request, a lost response after a successful write, a worker crash, expired approval, and a retry after permissions change. Check both the external state and what the user sees.
Log the action ID, attempt count, outcome category, and correlation ID where permitted. Keep sensitive arguments out of logs and provide a way to investigate an unknown outcome.
A timeout walkthrough
A user approves creating one ticket. Your application writes an action record with a stable key and the approved arguments, then calls the ticket service. The service creates the ticket, but the response is lost before your worker receives it.
The worker should mark the outcome as unknown and look up the action through the provider's supported reconciliation method. If the existing ticket is found, record its identifier and report the confirmed result. If the provider cannot confirm whether the write happened, send the case to an operator instead of issuing an unbounded series of creates.
A unique key only helps if the system that owns the operation enforces it atomically and keeps the result for an appropriate period. Test concurrent workers as well as sequential retries. Also verify that an expired approval or changed user permission stops the retry.
Provider retries and action retries solve different problems
A model API request may receive a temporary rate-limit response before any action is proposed. Separately, an agent may request an application tool that writes to an external system. Each layer needs its own deadline, retry policy, and record of what happened.
An SDK may already retry eligible provider errors. Adding another retry loop without checking its settings can multiply attempts and delay recovery. A retry of the model call also does not make a downstream ticket creation safe; that write needs its own idempotency and reconciliation design.
For a streaming response, track what was delivered before deciding how to recover. A late error cannot always be handled as if no output or tool action occurred. Test your recovery path with synthetic users and actions before enabling it for real records.
Sources and further reading
Documentation reviewed November 9, 2026. Verify current model support, limits and pricing before implementation.
