October workshops are openBuild a Search AI Agent$99 early bird

Enroll now
Skip to content

PHASE 4 · LESSON 15 OF 24 · 3 SMALL IDEAS + A GUIDED LAB

Fail clearly and recover carefully

A full room and an unreachable room service require different next steps.

You will learn to: Retry only explicitly temporary read failures, stop at a bound, and preserve unsuitable or unknown outcomes.

Preparing your lesson and this browser’s progress…
Read the complete lessonAll the ideas in one place · works without the editor

Use these notes to review a concept or read at your own pace. The interactive workspace above adds predictions, editable code, and actual run results.

IDEA 1

An unsuitable result is not a failed call

A tool can execute successfully and return an answer you do not want. If an availability service reports that a room is full, the read worked. Calling it again immediately does not make the room suitable. By contrast, a temporary service error means the observation was not obtained and a retry may be reasonable.

Use explicit result categories rather than interpreting every disappointing answer as an error. This fixture returns ok with an availability value, temporary_error, or fatal. An unknown category also stops the controller. The categories are authored examples, not a promise that every real service uses these names; a real adapter must map documented errors carefully.

Repeating a read is also different from improving a plan using feedback. In a Reflexion-style design, a later trial receives a note about the earlier failure. That note does not repair a broken service or grant permission to repeat a write. Choose the recovery mechanism that matches the failure.

Classify before reacting

  1. Observation. The read succeeded but the room is unavailable.
  2. Temporary failure. The read produced no usable observation.
  3. Other failure. Stop when retryability is not established.

Follow this authored example, then test the idea in the lab.

Read the example

if (result.status === "ok") {
  return { status: result.available ? "available" : "unsuitable", attempts };
}

A valid unavailable result ends this task. It should not be silently retried until a favorable answer appears.

Think it through: A successful tool response says available: false. Should this controller retry it as a service failure?

IDEA 2

Use timeouts and bounded retry policies

A retry policy states which failures qualify, how many attempts are allowed, and how long the operation may take. A timeout bounds waiting for one attempt; a total deadline bounds the whole task. Real services often use backoff to space retries and jitter to avoid many clients retrying at the same instant.

Our synchronous fixture cannot wait on a network. It returns a scripted sequence immediately, allowing you to see the control flow without claiming to implement real delays. The controller allows at most three attempts and retries only temporary_error. Exhaustion returns unknown, because three failed reads do not establish whether the room is free.

Bound the recovery loop

  1. Attempt. Make one read and inspect its status.
  2. Retry decision. Only a declared temporary error can continue.
  3. Stop. Three failed attempts leave availability unknown.

Follow this authored example, then test the idea in the lab.

Read the example

for (let attempts = 1; attempts <= 3; attempts++) {
  // read, classify, return on a usable or non-retryable result
}
return { status: "unknown", reason: "retry_limit", attempts: 3 };

The loop bounds call count. It does not implement backoff or a network timeout; those belong in a real asynchronous adapter.

Think it through: All three reads return temporary_error. What has the controller learned about availability?

IDEA 3

Keep repeated actions from duplicating effects

A timeout on a read usually leaves a missing observation. A timeout on a write is more complicated: the server may have completed the booking even though the response did not arrive. Repeating the write could create a duplicate. Whether a retry is safe depends on the operation's semantics, not just the error message.

An idempotency mechanism lets a service recognize repeated requests for the same intended action and avoid applying that action again. It needs server-side support and an appropriate key lifetime. Adding a random field named idempotencyKey does not create that behavior. This lesson only retries a read; its transfer task asks you to design a careful write recovery separately.

A lost reply does not mean no action

  1. Request. A booking write reaches the service.
  2. Lost reply. The caller cannot tell whether the write completed.
  3. Reconcile. Use the service's documented idempotency or status lookup.

Follow this authored example, then test the idea in the lab.

Read the example

// Design sketch, not a browser tool:
// Reuse a supported operation key for the same intended write.
// Check its stored status before issuing a different write.

This is an architectural sketch. No write service or idempotency store exists in the browser lab.

Think it through: A booking request timed out after it was sent. What is the dangerous assumption?

Put it into practice

Handle successful, temporary, and unknown statuses with a maximum of three availability reads.

  1. Read the selected case and predict its expected result.
  2. Run the starter once. Use the failed check and tool trace to locate the missing rule.
  3. Insert the explained snippet at the TODO, then run the case again.
  4. Test all three cases. Change the experiment input and explain whether the same rule still works.

Your next experiment: Start with an unfamiliar status called permission_denied, followed by a successful reply. Explain why the controller must stop before reading that second response.

Retry only a known retryable failure, within a limit, and never turn missing evidence into success.

Key terms

Backoff
Spacing retries rather than immediately repeating every failed request.
Timeout
A bound on how long to wait for an operation.
Idempotency
A supported operation behavior that prevents repeating the same intended action from adding duplicate effects.

Sources and scope

Original Stemtiq teaching, reviewed 2026-09-14. The named researchers and organizations do not endorse this course. Classroom cases are authored exercises, not published findings.

Amazon Builders’ Library · Marc Brooker: Timeouts, retries, and backoff with jitter

PDF copyright 2019 · reviewed 13 September 2026

Handle transient failures with timeouts and bounded retries, consider backoff and jitter, and establish whether repeating an operation is safe.

Retries can amplify overload or duplicate side effects. Three immediate classroom attempts are an exercise rule, not a universal policy for real services.

Anthropic: Writing effective tools for agents — with agents

11 September 2025

Design distinct tools with clear parameters, relevant returned information, and evaluations of how the agent actually uses them.

A description or schema does not guarantee the right action. A live tool can return different data for the same arguments as its environment changes.

Shinn et al. · NeurIPS: Reflexion: Language Agents with Verbal Reinforcement Learning

20 March 2023 · v4 revised 10 October 2023 · reviewed 14 September 2026

Use feedback from an attempted task to form a textual note that can inform a later attempt, without updating model weights.

The feedback or its interpretation can be wrong. A stored note neither guarantees improvement nor fixes a failed service; this lesson does not reproduce the paper's experiments.

Your JavaScript really runs. The model decisions and school data are authored simulations, so you can learn without an API key. Every workspace also includes a separate real SDK example to explore next. Passing the lab’s cases is practice, not proof that an agent is ready for real-world use.