Claude Code stuck: hung, looping, or waiting
Tell a hung Claude Code session from a loop or a waiting prompt, what to do for each, and how a team sees one repeating a call five times in three minutes.
A Claude Code session that stopped moving is in one of three states, and the terminal shows all three the same way: a hung process, a loop, or a prompt nobody has answered. The first needs Ctrl+C and claude --resume; the second needs someone to notice before it drains the week's window; the third needs one keypress from whoever can see the question. Caprock tells the three apart for every session on the machine, and the team edition for every machine.
Three states that look the same from the terminal
A terminal shows the last thing drawn on it. A process that stopped answering, an agent repeating one command, and a dialog waiting under a spinner that stopped all leave the same still screen. The difference is in the process and in the stream of events it writes, which is where Caprock reads it: each session carries one of working, idle, waiting on you, done, looping or error.
| What you see | What it is | What to do |
|---|---|---|
| No new text, no spinner, keys do nothing | Hung: the process stopped answering | Ctrl+C. Then close the terminal and claude --resume |
| Spinner on, the same command or edit scrolls past again | Looping: one call repeated | Esc, then say what is wrong and what to do instead |
| Spinner off, a dialog or a question at the bottom | Waiting: a permission prompt or a question is open | Answer it. Nothing happens until someone does |
Usage limit reached · limit resets 3:45pm | Not stuck: waiting for the window to reset | Leave it. Esc at an empty prompt cancels the wait |
The three need three different people: the hung one needs you at the keyboard, the loop needs anyone who can read the transcript, the waiting one needs whoever the question was for.
A hung Claude Code: what the troubleshooting page says
Anthropic's troubleshooting page has one section for it, "Command hangs or freezes", read 30 October 2026:
If Claude Code seems unresponsive: 1. Press Ctrl+C to attempt to cancel the current operation. 2. If unresponsive, you may need to close the terminal and restart.
Then: "Restarting doesn't lose your conversation. Run claude --resume in the same directory to pick the session back up." The keys that stop a turn without closing the session, from the interactive-mode page the same day:
- Esc. "Stop the current response or tool call mid-turn so you can redirect. Claude keeps the work done so far."
- Ctrl+C. "Interrupts a running operation. If nothing is running, the first press clears the prompt input and a second press exits Claude Code."
- Esc, Esc. "When the input is empty, double
Escopens the rewind menu", to go back to an earlier point in the code and the conversation. - Ctrl+D. "The first press shows a confirmation hint and a second press within 800ms exits."
- Ctrl+Z. "Unix only. Suspends the process to your shell; run
fgto resume"
To come back after a restart: claude --continue. "This resumes the most recent session in the current directory; if there isn't one yet, it prints No conversation found to continue and exits." "Use claude --resume to choose from a list, or /resume from inside a running session."
What the same page says about the two causes that look like a hang:
- Memory. "If a session's heap memory passes 2.5GB, a critical memory usage warning appears. To free the memory, restart Claude Code and run
claude --continueto resume the conversation in a fresh process." Before that,/compact, a restart between large tasks, andclaude --safe-modeto test whether a plugin, MCP server or hook is the load: "It disables all customizations for the session; if usage drops, see Debug your configuration to find which one". - Compaction thrashing.
Autocompact is thrashing: the context refilled to the limit...means automatic compaction succeeded but a file or tool output immediately refilled the context window several times in a row. Claude Code stops retrying to avoid wasting API calls on a loop that isn't making progress. Read the large file in ranges,/compactwith a focus, move the work to a subagent, or/clear. - A very large table. "Before v2.1.208, Claude Code rendered every row, so resuming a session that contained a very large table could stall while it re-rendered."
- The checkup. "run
/doctorinside Claude Code for an automated check of your installation, settings, extensions, and context usage; it proposes fixes it can apply after you confirm". "Ifclaudewon't start at all, runclaude doctorfrom your shell instead."
The page names no time after which a turn counts as hung. A session that is quiet because a long command runs, and one whose process has stopped, read the same at the terminal; Caprock's session row shows the last event's time and the command it is on, which is how you tell a 20-minute test suite from a dead process without killing either.
Claude Code stuck in a loop: what Caprock raises, and when
A loop in the transcript is one tool call, then the same call, then the same call: an edit whose old_string is not in the file any more, applied five times; a command that fails and is run again unchanged; a script re-run against the same error. Every repeat re-sends the whole conversation to the model, so the loop costs what the context costs, each time, and spends the five-hour and the weekly window with it (Claude usage limits).
Caprock's rule, as internal/config/config.go and internal/loop/loop.go state it: 5 calls of the same tool with similar input within 3 minutes raise one alert, per session and per subagent, once per episode. "Similar" means the tool name and its input with numbers, hex hashes, temp paths and whitespace collapsed, and an edit's text compared on its first 200 characters, so a retry counter or a line number does not hide a loop. description, timeout, run_in_background are ignored. Both numbers are yours to change in config.json (loop_k, loop_t_minutes).
Two kinds of call never count:
- Read-only tools:
Read,Glob,Grep,ToolSearch,NotebookRead. Measured on 64,733 tool calls of one developer's history, the detector fired 436 times, and 236 of those, 54%, were a repeated Read of one file: re-reading after an edit, or while searching. A tool call is billed at $0, so none of them was about the budget; leaving them out cut the alerts to 174. - A browser looking or moving: a screenshot, a scroll, a wait, a key, navigation. Five identical screenshots in three minutes is how a browser tool works. A repeated click, typed text or script still counts.
What you get is one card, the same on the Now screen, in the Agent panel and on the session page. It says one sentence, in the form caprock ran the same command 5 times in 3 minutes (python3 …/p2e.py), with the whole input on hover and the span measured from the first call to the last. Under it, two figures each named for what it is: the context those calls re-read, at cache-read rates, and the session total. Then three actions:
- Tell the agent opens the message Caprock would send, editable, and sends it through the session's own message queue: typed in at once when the agent is idle, otherwise when its turn ends. The text opens with
[Caprock]and ends "(Sent by Caprock's loop alert — not by the user.)", so the agent does not take a heads-up for an instruction from you, and it carries the exact repeated input, which the agent will recognise. Offered only for a session Caprock started; Caprock never types into a process it did not start. - Open session goes to the timeline at the first repeated call, for a session you started in your own terminal.
- Dismiss puts the card away until the detector raises a new alert and sends nothing.
What to tell the agent, in your own words or the card's: name the exact call, say it has run 5 times with the same result, and say what to do instead: read the error it is getting, try a different approach, or stop and report. Esc in the terminal does the same from the keyboard, and "Claude keeps the work done so far."
One thing the card never says is "stuck". The session page's hour view counts ×N same call, the most-repeated identical call in six minutes, and it is worded as a measurement, not a verdict: polling a file with repeated reads looks exactly like being stuck, and only the person working knows which it was.
Waiting on you: permission prompts and questions
The third state is the quietest. Claude Code drew a permission dialog, or asked a question with AskUserQuestion, and the turn is paused until someone answers. In the terminal the spinner is gone and the dialog sits at the bottom; from across the room, or from another machine, it looks like an agent that finished. The interactive-mode page notes the shape of the problem itself: while a session waits for a usage limit to reset, "Claude Code still asks for permissions as usual, so the task can stop on a prompt while you're away."
Caprock stores the dialog as it is drawn. Claude Code's PermissionRequest hook fires for every session on the machine; Caprock forwards it and never answers it, so the dialog appears exactly as without Caprock, and keeps it as a permission.prompt event. From that event the session reads waiting for approval, naming the call; waiting for your answer for AskUserQuestion; plan to approve for a plan. A turn that ended without a dialog is read from its last message: on 4,133 turn ends on one developer's Mac, 19 August to 21 October 2026, 16% ended asking something, and those read waiting on you too, marked as a guess you can correct.
The row on the Now screen appears once a session has waited 15 minutes by default: a question asked two minutes ago is not a problem. It names the session, not only the project, and what did it ask? opens the question in place. The row is one button into that session: in the desktop app its tab, a terminal when Caprock started it and a read-only view when your own terminal holds it. There is no "all clear" state; the strip is empty when nothing is wrong, because an always-on banner teaches people to stop reading the space where the warning will appear.
Your phone hears it through your own Telegram bot. Set up a bot in Settings and switch the alert on; it is off until you do, and free. The message says which agent, project and session, what happened, the folder and branch, and for a dialog the tool and the command, file, URL or question it asks about, clipped to 100 characters; a finished run adds its duration, cost, tool calls and changed files and, unless you switch it off, the first line of the final reply (120 characters). Code, diffs and tool output are never sent, and nothing is sent until you set up a bot. A needs-approval message goes at once; a finished one after a minute with nothing new, so an owner replying at the keyboard is never paged; at most one of a kind per session in 3 minutes and 20 an hour across all sessions. Under it, a link to the session on the address phone access listens on, left out when phone access is off.
The fix that is not one: --dangerously-skip-permissions. It removes the waiting state by turning off permission prompts and safety checks, protected paths included; only ask rules and a few critical actions still prompt. The permission-modes page's own warning is to use it "in isolated environments like containers, VMs, or dev containers without internet access, where Claude Code cannot damage your host system." On a team it also removes the one moment a person reads a command before it runs. Allow rules for the commands you trust, auto mode, and an alert that reaches a phone answer the same problem without it: claude --dangerously-skip-permissions.
Codex stuck
Codex's developer-commands page for the CLI, read 30 October 2026, documents the controls:
/status— "Display session configuration and token usage." "Review the output for the active model, approval policy, writable roots, and current token usage."- Close. "Press Ctrl + C or run /exit to close the session."
- Steer. "Press Enter while Codex is working to inject new instructions into the current turn."
- Fork. "Press Escape twice with an empty composer to edit the previous user message and fork the chat from that point."
- Come back.
codex resume: "Reopen a recent chat from the current repository, or search across local chats when you need to return to older work." In a script,codex exec resume --last: "Resume an exec session by ID or add --last to continue the most recent session from the current working directory."
What the page does not list is a key that stops the turn and keeps the session, the way Esc does in Claude Code; Ctrl + C closes it. OpenAI's troubleshooting page covers the desktop app and says nothing about a hung CLI. What exists is the issue tracker. Three reports open on 30 October 2026, as their authors titled them:
- #58259, 30 October 2026: "CLI TUI stops accepting keyboard input when account/rateLimits/read times out"
- #57996, 29 October 2026: "Desktop app (Linux): Spotlight window stuck in hide loop, main process at 100% CPU, app shows 'Not Responding'" (a Desktop app report, not the CLI)
- #58267, 30 October 2026: "[Dots][GitHub] Git-tree approval prompt repeatedly resurfaces while delegated task stays in progress"
These are reports, not facts about the product; the third is the waiting state wearing Codex's clothes, an approval prompt that keeps coming back while the task sits.
Caprock reads Codex's own session files and stores each tool call in the same shape as Claude Code's, with shell and exec calls described by the line they ran, so the loop detector above runs over Codex sessions with the same 5-in-3 rule and names the shell command on the card. A call still without a result when Codex's own record says the turn ended is marked interrupted, from that record, not from a clock. Codex writes no approval prompt in a form Caprock reads, so the waiting row and the phone alert are Claude Code's for now.
What one session can cost
The reason a loop matters is what a session spends. The heaviest session in thirty days on my Mac, 29 September to 28 October 2026, priced at API list rates as Claude Code's own /usage prices it:
- 373 h
- one session, start to end
- 64,039
- tool calls in it
- $3,465
- at list, an estimate, not a bill
That is 47% of the month's $7,409, in one session. It was not a loop. Checked against its own stored calls on 30 October 2026: the most-repeated non-read-only call inside any three-minute window was 18 Edits to one file, each a different edit; by the detector's own signature the densest repeat was 7 runs of one query; 53 screenshots in all 373 hours. It was long work, at $9 an hour on average. A session that size is where the detector earns its place: an hour of it looping costs what an hour of it working does, and nobody at the keyboard is the one who notices.
That is also why the figure beside the loop card is labelled session total and never the loop's cost. The session's whole spend, bare beside "stuck in a loop", read as the price of the repetition: a $58.85 the loop had not cost. Charging the loop's own window instead was tried and was wrong too: measured on a real 2-hour loop, its window held $47.64, every cent of it the useful work happening alongside: the 176 repeated calls billed $0.00, the 389 turns beside them the $47.64. So the card keeps the number what it is and says so.
Can anyone on the team see a loop before the week's quota is gone
On one machine the loop card is seen by whoever is looking at that machine, and a loop on a laptop whose owner went to lunch is seen by nobody until the window is gone. Caprock for Teams moves the alert off the laptop: the detector runs on each machine as above, and the team view shows it to anyone on the team, with the session and the repository, while the window still has something left.
The team screen reports by work unit, not by person: cost, sessions and stuck-session counts per repository, per PR, per release, per week. A per-person view is a documented switch the team turns on knowingly, off by default, and every developer's own dashboard shows the same aggregates the lead sees. What the reporter sends is what the free product already computes, session identity, totals and the activity phrase. "It never sends prompts, replies or tool output. That is not a setting: the payload has no field for them, so a misconfiguration cannot leak one."
Buying Caprock is one flat price for the team.
Questions people ask
- Why is Claude Code stuck?
- One of three things: the process stopped answering, the agent is repeating one tool call, or a permission prompt or question is open and nobody has answered it. The terminal shows all three as a still screen; the process and its event stream tell them apart. Caprock marks each session working, idle, waiting on you, done, looping or error.
- What do I do when Claude Code is not responding?
- Anthropic's troubleshooting page: "Press Ctrl+C to attempt to cancel the current operation", and if that does nothing, close the terminal and restart. "Restarting doesn't lose your conversation. Run `claude --resume` in the same directory to pick the session back up." Esc stops a turn and keeps the work done so far; a second Ctrl+C with nothing running exits.
- Claude Code is frozen with a memory warning. What now?
- The page says the warning appears when a session's heap passes 2.5GB; restart Claude Code and run claude --continue to carry the conversation into a fresh process. /compact lowers it; claude --safe-mode disables every plugin, MCP server and hook for one session to see whether one of them is the load.
- How do I know Claude Code is stuck in a loop?
- The same tool call with the same input, again and again, in the transcript. Caprock raises one card when 5 similar calls of one tool land within 3 minutes, per session and per subagent; reads, searches and a browser's screenshots and scrolls do not count. Tell the agent sends the exact call back to a session Caprock started, through its message queue.
- Why does Codex get stuck?
- OpenAI's troubleshooting page covers the desktop app and says nothing about a hung CLI; the tracker holds the reports, three of them cited on this page, including a TUI that stops taking keys and an approval prompt that keeps returning. The CLI's developer-commands page gives /status for the model, approval policy, writable roots and token usage, Ctrl + C or /exit to close, and codex resume to come back. Caprock runs its loop detector over Codex sessions with the same 5-in-3 rule.
- How do I see a stuck agent on another machine?
- On one machine, Caprock's Now screen and its phone alert through your own Telegram bot, which says which agent, project and session, what happened and what the dialog asks about, clipped; code, diffs and tool output are never sent. Across machines, Caprock for Teams shows the loop alert and stuck-session counts per repository to anyone on the team, by work unit, with no prompt or tool output leaving the laptop.
Sources
- Claude Code docs — Troubleshooting (command hangs or freezes, high CPU or memory, auto-compaction thrashing, /doctor and claude doctor, search), read 30 October 2026 as the page's .md route
- Claude Code docs — Interactive mode (the shortcuts table: Ctrl+C, Esc, Esc Esc, Ctrl+D, Ctrl+Z; cancelling a question; waiting for a usage limit), read 30 October 2026
- Claude Code docs — Common workflows (resume previous conversations: --continue, --resume, /resume), read 30 October 2026
- Codex docs — Developer commands, CLI surface (/status, Ctrl + C and /exit, Escape twice, Enter while Codex works, codex exec resume --last), read 30 October 2026; developers.openai.com/codex/cli/reference redirects here
- Codex docs — Codex CLI (codex resume), read 30 October 2026; developers.openai.com/codex/cli/features redirects here
- Codex docs — Troubleshooting (the desktop app; nothing on a hung CLI), read 30 October 2026
- openai/codex issue #58259 — "CLI TUI stops accepting keyboard input when account/rateLimits/read times out", opened 30 October 2026, open on 30 October 2026; a report, not a fact about the product
- openai/codex issue #57996 — "Desktop app (Linux): Spotlight window stuck in hide loop, main process at 100% CPU, app shows 'Not Responding'", opened 29 October 2026, open on 30 October 2026; a report, not a fact about the product
- openai/codex issue #58267 — "[Dots][GitHub] Git-tree approval prompt repeatedly resurfaces while delegated task stays in progress", opened 30 October 2026, open on 30 October 2026; a report, not a fact about the product
- Caprock source — internal/config/config.go, Defaults(): LoopK 5, LoopTMinutes 3
- Caprock source — internal/loop/loop.go: the signature, the read-only and browser-observation exclusions and the measurement behind them, one alert per episode, the Alert.TaxUSD comment on why the loop's cost is never stated
- Caprock architecture — Loop detector: the rule, the defaults, the alert count after the read-only exclusion, each thread counted apart
- Caprock source — ui/src/lib/loopalert.ts and ui/src/components/LoopAlertCard.tsx: the card's sentence, Tell the agent / Open session / Dismiss, the [Caprock] message and its closing line
- Caprock build status — 2026-09-03 (later): the $58.85 misread, the two-hour loop's window, why the figure stays the session total; the rejected all-clear banner
- Caprock UI spec — the attention strip: the waiting row's fifteen minutes, what did it ask?, the one-button row, ×N same call in six minutes
- Caprock contracts — PermissionRequest stored as permission.prompt; Needs you and Done (permission, question, plan, asks, done); § Phone alerts, the message as built
- Caprock decisions — ADR-036, amended 2026-10-05: a phone hears that a session needs it through the owner's own Telegram bot
- Caprock — the team edition: aggregates by work unit, stuck-session counts per repository, no field for content, the person dimension a switch
- Caprock's measured figures: the heaviest session of 29 September to 28 October 2026, one developer's Mac at list price, and the thirty-day total; the charts on /teams/ read the same file (src/content/charts.ts)
Try it
The record of every coding agent you run, the sessions it did not start included. Free, open source; nothing leaves your machine.
Notarized by Apple. One file for Apple silicon and Intel, macOS 13 or later.
Or run it yourself:
Paste in Terminal: it installs Caprock and opens it.Or with Homebrew: brew install --cask dspv/tap/caprock-app