Tracing the Agentic Loop Through a Real Task
A developer runs Claude Code in a Node.js project and types:
"The
/api/ordersendpoint returns a 500 error when a user has no shipping address on file. Fix it."
They are in Manual permission mode.
- Describe, phase by phase (gather context → take action → verify results), a plausible sequence of tool calls Claude Code would make to handle this request. Name at least one specific built-in tool per phase and what it would be used for.
- At which points in your trace would Claude Code stop and prompt the developer for approval, and why exactly those points and not others?
- Suppose the first fix Claude applies still fails the verification step (the test still fails, or a new error appears). Explain, in terms of the loop, why this doesn't mean Claude Code is "broken" — what should happen next mechanically?
1. A plausible tool trace:
Gather context: Claude doesn't know where /api/orders is handled,
so it likely starts with Grep searching for "orders" or the route
path itself to locate the relevant route handler file, then Reads
that file to see the actual code path. If the error message mentions a
stack trace or specific function, it may Read the shipping-address
lookup code directly. It might also run Bash (npm run dev logs,
or reproduce with a curl request) if it needs to see the actual
error rather than infer it from code alone.
Take action: Once it identifies the bug — say, code that assumes
user.shippingAddress is always non-null and dereferences a field on
it — it uses Edit to add a null check and either return a
meaningful 400/422 response or handle the missing-address case
explicitly, rather than letting the null dereference throw.
Verify results: it runs Bash to execute the relevant test file
(e.g. npm test -- orders) or, if no test covers this case, it may
first add a test with Edit/Write and then run it. It reads the
command's exit code and output to determine whether the fix actually
resolves the 500.
2. Where approval prompts occur:
In Manual mode, Claude Code auto-approves read-only actions — Grep, Read, and read-only Bash commands like running the existing test suite or checking logs — because they cannot change any state and therefore carry no risk to undo. It stops and prompts only before actions that change something: the Edit to the route handler, and any Edit/Write that adds a new test file. This is the reversibility principle in action: reads are free to reverse (there's nothing to reverse), so only the state-changing calls need a human checkpoint.
3. Why a failed verification isn't "broken":
A failed verification step is exactly what the loop is designed to catch and react to — it's the mechanism working as intended, not a malfunction. The correct behavior is for Claude to treat the test failure or new error as new context: it reads the updated error output, forms a revised hypothesis about what's actually wrong (maybe the null check was in the wrong function, or there's a second code path that also needs the same fix), and takes another action — another Edit — followed by another verification pass. This is the same gather→act→verify cycle repeating, not a new process. A user watching this happen should expect iteration, not a single one-shot patch; the loop only terminates once verification actually passes (or Claude determines it's stuck and asks the developer for help, e.g. "I can't reproduce the 500 locally — can you share the exact request that triggers it?").
Share this question