A chatbot action timeout is an unknown outcome
A support chatbot asks an integration to create a ticket. The request times out. What should it tell the customer?
"The ticket was not created" is too strong. A timeout can mean that the destination accepted the request and its response never reached the caller. Retrying immediately can create two tickets. Saying "Done" can leave the customer waiting for a ticket that never existed.
Treat an uncertain action as a state worth preserving.
Separate three things
The conversation records what the customer asked for. The execution record describes an attempt to carry it out. The destination holds the business outcome. Those records can disagree temporarily.
For a ticket request, a useful execution record contains an operation identifier, the intended destination, a timestamp, a safe summary of the requested action and any returned ticket identifier. It should not contain unnecessary customer secrets.
Use at least these outcomes:
| Outcome | Evidence | Customer-facing wording |
|---|---|---|
| Confirmed | Destination acknowledged the ticket and returned its identifier. | "Your request was created. The reference is…" |
| Rejected | Destination explicitly refused the request. | "I couldn't create the request. Here's another way to reach support." |
| Unknown | The request may have reached the destination, but there is no decisive result. | "I couldn't confirm whether it went through. I won't send another copy while that is being checked." |
The words should match the evidence. A successful HTTP response may still represent a queued operation rather than completed business work. Read the destination's documented meaning of success.
Make retries a product decision
An idempotency key can help when the destination supports one. Reuse the same key for another attempt at the same operation. A new random key on each retry defeats the purpose. Check the provider's retention window and conflict rules before depending on this behavior.
If the destination does not support idempotency, look for a supported reconciliation method. A ticket identifier, an external reference field or a narrowly scoped search may help. Absence from a search result is not always proof of absence: indexing and asynchronous processing can lag.
For an irreversible or costly action, unresolved uncertainty may need a human. For a harmless read, a bounded retry may be reasonable. Apply that distinction to the action, not to how confident the language model sounds.
Test the awkward timing
A happy-path test cannot expose this failure. Add a test in which the destination commits the operation but the caller loses the response. Then check both the destination and the conversation:
- Does exactly one business operation exist?
- Does the conversation avoid a false success or failure claim?
- Can a later worker reconcile the operation without creating a fresh one?
- Is there a clear route for the customer if reconciliation remains unresolved?
Also test an explicit rejection. A design that labels every failure "unknown" can become needlessly paralyzed.
The useful boundary is between evidence of an outcome and evidence that an attempt occurred. Keep both. That distinction matters whenever a chatbot moves from answering questions to changing something outside the conversation.
Written by the Agentkit team with AI assistance. This is a design pattern for chatbot integrations, not a claim that every integration implements the same retry guarantees.
