Should Botie Repeat the Request, or Find Out What Happened?
A Lost Answer Leaves the Caller Unsure What Happened
BOTIE
HTTP, the request-and-response protocol used by web services, supplies status and method rules. RFC 9457, published in 2023 as a replacement for RFC 7807, adds a standard format for more specific problem details. A stable problem type lets the client recognise the category while the explanatory wording improves. We will use short outcome codes to decide what can happen next, and keep a lost answer separate from a confirmed failure.
Sources for this history
The Tool Timed Out After Creating the Job
Botie asks a service to start a training job. The connection drops before the answer arrives. A second request might recover from a temporary network problem. It might also start a second expensive training job, because the first request may already have succeeded.
An error message needs to tell the caller what it can safely do next. We must distinguish an invalid request from a temporary refusal, and distinguish both from an operation whose outcome we have not yet established. A timeout describes what the caller observed, not necessarily what the service did.
These components recommend a next action only. A real service must supply the operation record and enforce any idempotency guarantee before the caller relies on it.
Step 1 of 1
The same advice does not fit every failure
The service contract and the operation’s repeat behaviour determine recovery.
| Observed outcome | What is established | Next step here |
|---|---|---|
| Invalid request | The supplied operation was not accepted | Correct it; do not repeat unchanged |
| Temporary refusal | A retry may help | Repeat only if safe and within budget |
| Outcome unknown | The operation may have happened | Reconcile its state first |
| Success | A result was received | Use the result |
Invalid request
- What is established
- The supplied operation was not accepted
- Next step here
- Correct it; do not repeat unchanged
Temporary refusal
- What is established
- A retry may help
- Next step here
- Repeat only if safe and within budget
Outcome unknown
- What is established
- The operation may have happened
- Next step here
- Reconcile its state first
Success
- What is established
- A result was received
- Next step here
- Use the result
Give a caller a stable failure identity
Failure identity, repeat safety and budget remain separate inputs to the decision.
Give each tool failure the recovery it permits
Botie must recover without turning an unknown job outcome into duplicate work.
BOTIE
Next action for each observed tool outcome
- 0done
- 1retry
- 2stop
Follow the operations
1. Application outcome codes
- 0ok
- 1rate_limited
- 2invalid_request
2. Classify the structured tool outcome
- 0success
- 1transient
- 2permanent
3. Trusted safe-to-repeat flags
- 01
- 11
- 21
4. Attempts remaining after this observation
2
5. Decide whether repeating is permitted
- 0done
- 1retry
- 2stop
6. Result
- 0done
- 1retry
- 2stop
These components recommend a next action only. A real service must supply the operation record and enforce any idempotency guarantee before the caller relies on it.
1. Give a caller a stable failure identity
Suppose an invalid result count produces a response with a documented type. The caller can recognise that type and correct its arguments. The title and detail explain the occurrence to a person; changing those sentences should not force every client to rewrite its parser. An HTTP status still describes the broader response category.
Leave secrets and internal stack traces out of public details. Keep a safe operation identifier so the caller can later ask whether that particular training job was created.
The browser examples use short application codes. A real RFC 9457 response uses its documented media type and a type URI.
2. Classify before choosing an action
Sending the same invalid argument again will not repair it. A service that temporarily lacks capacity may be able to accept it later. A failed sign-in may require a new login. Those cases need different next steps, even though none returned the answer Botie wanted.
Our policy calls the temporary outcomes rate_limited and unavailable. The usual technical word for temporary is transient. We keep outcome_unknown separate: it means the caller still needs to find out whether the operation happened. An unrecognised code stops until the service’s documented handling is known.
outcomes = [rate_limited, invalid_request, outcome_unknown, ok]
safe to repeat = [1,1,0,1]
attempts remaining = 2
next actions = [retry, stop, reconcile, done]The same repeat flag does not make an invalid request valid. An unknown outcome needs investigation before another creation attempt.
A small machine-readable failure
This fixture separates a stable type from wording a user may read. It does not contact a service or perform a retry.
problem = {"type":"https://example.invalid/problems/invalid-count",
"title":"Invalid result count", "status":400,
"detail":"count must be an integer from1 to20"}
print(problem["type"].rsplit("/",1)[-1])
print(problem["status"])invalid-count
400A client can recognise the documented type while the explanatory sentence changes. The example.invalid URI is an invented documentation identifier.
3. Repeating safely is an operation property
An idempotent operation has the same intended effect when repeated as when performed once. That does not mean it produces identical logs or uses no extra compute. Prediction may be repeatable while a tool that creates a purchase, sends a message or starts a job needs stronger handling.
An idempotency key can identify one logical operation if the service documents and enforces its scope, lifetime and behaviour for changed arguments. Adding an arbitrary key to a request does not create those guarantees.
The workshop’s safe-to-repeat flags are supplied policy facts. They must not be trusted merely because a model put true in its tool arguments.
4. A lost response leaves two possible histories
After a lost create-job answer, there are still two possible histories: the job exists, or it does not. Keep the original operation ID and ask the service for its recorded result. This lookup is what reconcile means here. Finding the existing job avoids creating it again. A definite failure or confirmed absence may permit a retry under that service’s rules.
If the service cannot resolve the uncertainty, report it. Calling the request successful would invent an answer, and creating a fresh operation could duplicate the work.
The browser simulation recommends reconcile. It does not implement an operation ledger, durable delivery or a network recovery protocol.
Check yourself
Questions on Parts 1 to 4
Question 1 of 2
What is known?
Use the information below.
A create-job request loses its response. The client has no authoritative result yet.5. Bound waiting as well as the number of attempts
Even a safely repeatable request can cause trouble if every waiting client sends it again immediately. A backoff policy increases or otherwise spaces the waits between attempts. Small random differences in those waits, called jitter, can stop clients from all returning at the same instant. Respect the server’s documented Retry-After instruction as well.
The user still needs an answer within an overall deadline, so also bound the attempts and total wait. Retry-After can contain a date or a number of seconds. Interpret the documented form before deciding whether another wait fits.
server minimum wait = 3 seconds
local backoff = 1 second
chosen wait = max(3,1) = 3 seconds
remaining wait budget = 2 seconds
result = stop waiting; no retry fits this budgetThe exercise receives already parsed seconds. A production caller must also leave time for the next operation itself.
6. Review retries across the whole call chain
A browser, gateway, SDK and worker can each retry. Their combined number of attempts may greatly exceed the one loop you inspected. Assign ownership of recovery and preserve the logical operation identity across layers.
Record attempt counts, stable error categories and final outcomes. Separate a successful retry from an unresolved operation so observability does not turn uncertainty into a success rate.
A temporary-failure label is evidence about this attempt. It does not establish that repeating a side effect is safe.
7. Keep failure behaviour compatible too
An older agent may know how to handle a documented invalid-count problem but not a newly invented replacement code. Keep supported error types stable or version their changed meaning. Test recovery branches alongside successful requests.
Use synthetic failures in local tests: an invalid request must stop, a bounded repeatable refusal may retry, and an uncertain side effect must reconcile. These tests should not send real messages or start training jobs.
The challenges calculate decisions only. No code here creates a network operation, waits in real time or grants permission to repeat an actual side effect.
Check yourself
Questions on Parts 1 to 7
Question 1 of 4
What should this lesson’s policy return?
Use the information below.
Outcome=rate_limited, repeat_safe=False, attempts_left=3.Try it with Botie
Build with Botie
Write and run Python