Playbook

How Do You Know When a Coding Agent Is Stuck, and What Do You Do About It?

Oct 25, 2026 · 6 min read · by Jordan Kwan

A robot walking a circular track past the same broken signpost under a dark studio sky

TL;DR: A coding agent is stuck when its work stops changing in ways that matter. The reliable signals are repetition without progress: the same failing test or error across several attempts, edits that rename or rearrange without touching the cause, a diff that keeps growing while the goal stays unmet, tool calls that loop over the same files, and confident summaries that do not match the state of the code. The response is a ladder, not a single trick. Check the goal is still clear, give the agent the missing evidence, shrink the task, change one variable such as the approach or the model, restart from a clean state with a written summary, and finally take the task back yourself. Time alone is not the signal. Lack of verified progress is.

Key Takeaways

  • This is a framework piece. No measurements, completion rates, or universal time limits are claimed; thresholds below are decisions for your team to set, not findings.
  • Judge stuckness by progress against a checkable goal, such as a named test passing or a reproduced bug disappearing, never by how busy the agent looks.
  • The core signals are loops: repeated errors, repeated edits, repeated reading, and a growing diff with a static outcome.
  • Intervene on a ladder from cheapest to strongest: clarify, inform, shrink, redirect, restart, reassign.
  • Killing a run early and keeping its artefacts is a normal outcome, not a failure of the operator.

What does stuck actually mean for a coding agent?

A human developer who is stuck usually knows it, or can be asked. A coding agent will continue indefinitely, producing fluent activity that resembles work. It will edit, run, explain, and edit again, and each step reads plausibly in isolation. Stuckness is therefore a property you have to detect from the outside, from the pattern of the run rather than from the agent's own account of it.

Define it operationally: a run is stuck when additional steps are not reducing the distance to a checkable goal. That definition requires a checkable goal to exist, which is why the first failure in many stuck runs happens before the agent starts. Fix this bug, with no reproduction, no named test, and no statement of done, gives the operator no instrument to read. You cannot tell whether the agent is stuck, and neither can the agent.

What are the signals you can actually observe?

The same failure repeats. The agent runs the same test, hits the same error, and responds with variations of the same fix. Wording changes, the error does not. Two repetitions are debugging. A pattern of them, with no new hypothesis stated, is a loop.

The diff grows while the outcome does not. Productive runs usually converge: early exploration touches many files, then changes concentrate. A stuck run sprawls. New files appear, helpers are added, code is reorganised, and the original failing case still fails. Diff size is easy to watch and hard for the agent to disguise.

Summaries and reality diverge. The agent reports that a problem is fixed, or nearly fixed, while the check you defined still fails. Treat any summary as a claim to verify against the test, the reproduction, or the running behaviour, never as evidence itself. Divergence once is optimism. Divergence as a pattern means the run's feedback loop is broken.

The goal quietly changes. A stuck agent often renegotiates the task: it solves a neighbouring problem, weakens a test, adds a workaround that bypasses the failing path, or declares an edge case out of scope. Some renegotiation is good engineering judgement. Unannounced goal drift in a run that is not finishing its original task is a stuck signal wearing a productivity costume.

What is the intervention ladder?

Work from the cheapest intervention to the strongest, and change one thing at a time so you learn which change mattered.

1. Restate the goal and the check. Write, in the run or in a fresh instruction, the exact outcome and the exact verification: this test passes, this reproduction script prints this, this page renders this. Failure mode addressed: the agent was optimising for a vaguer goal than yours.

2. Supply the missing evidence. Agents loop most often on absent information: the real error output, the relevant log, the failing input, the constraint nobody wrote down. Paste the evidence into the run rather than describing it. Failure mode addressed: the agent was guessing at a cause it could not observe. The measurement mindset in we measured AI coding productivity applies at run scale too; claims improve when someone insists on looking at the artefact.

3. Shrink the task. Cut the run to the smallest sub problem that still matters: reproduce only, fix one file only, make one test pass without cleaning up anything else. A smaller task gives the agent a shorter loop and gives you a cleaner stuck signal if it still cannot converge. Failure mode addressed: the task required holding more moving parts than one run can manage.

4. Redirect the approach. If the agent has tried one strategy repeatedly, name the strategy, forbid it plainly, and require a different one: work backwards from the test, inspect the dependency instead of the caller, write a minimal reproduction outside the codebase first. Failure mode addressed: a locally reasonable approach that happens to be wrong for this bug.

5. Restart clean, carrying a written summary. Start a new run or session, and hand it a summary you write or edit: the goal, the check, what was tried, what was ruled out, and what the current best hypothesis is. Restarting discards polluted context and accumulated half edits while keeping the learning. Failure mode addressed: the run's own history became the obstacle. Do not restart by simply repeating the original prompt and hoping; that recreates the loop with extra steps, a pattern familiar from every agent demo works until you give it real work in reverse, where the second attempt looks fresh and fails identically.

6. Change the tool or the model, or take the task back. Some tasks exceed what a given setup can do, and some tasks turn out, on inspection, to need a decision only you can make. Reassigning the task to yourself is a legitimate final rung. The sunk cost of a long run is not a reason to fund a longer one.

When should you kill a run outright?

Kill immediately when the run is damaging things outside its brief: editing files it was not asked to touch, weakening or deleting tests to make them pass, rewriting working code far from the problem, or taking actions outside the codebase entirely. Those are not stuck signals; they are stop signals, and the correct intervention is to end the run, inspect the diff, and revert what you did not ask for.

Kill also when the ladder is exhausted: you have clarified, informed, shrunk, redirected, and restarted, and the check still does not move. At that point the run has given you information, namely that this approach in this setup will not finish this task, and further steps are spending money to confirm it.

How do you make stuck runs rarer?

Prevention is mostly task design. Start runs with a checkable goal, a stated scope, and a named verification step. Ask for a plan before edits on anything larger than a small fix, and read the plan for goal drift while it is still cheap. Set a checkpoint habit for yourself: at natural intervals, compare the current diff and test state against the goal, and run the ladder early while interventions are still cheap.

Written by Jordan Kwan, founder of Reachium.

I build Reachium, the LinkedIn outreach platform behind the tactics you just read. Same brain, live product.

See what Reachium does ↗

Prefer the long version first? What Reachium is and how it works