Claude Code stuck thinking: symptoms and first fixes
“Claude Code stuck thinking” is usually one of four failures: frozen on Starting, 0 tokens with no output, a permission prompt nobody answered, or a loop retrying the same request. Each has a different first fix. Here’s how to tell them apart, and what to try before you restart anything.
Key takeaways
- Press Esc and re-prompt first. It ends the wedged turn and keeps your context and file changes.
- A hung run doesn’t cost you the transcript.
claude --resumeorclaude --continuebrings back the conversation, plan and edited files. - An unanswered permission prompt is the most common reason a run seems to do nothing. Scroll up before assuming a crash.
- If nothing on screen changes across two checks a few minutes apart, treat it as stuck. Ticking tokens or new tool calls mean it’s still working.
Why does Claude Code get stuck on ‘Starting Claude Code’?
A hang at launch happens before your prompt is sent. Claude Code is trying to reach the API or your identity provider, and two causes cover most cases.
Auth or version mismatch. If you switched accounts, logged out elsewhere, or updated Claude Code in one terminal but not another, the CLI can stall on a token it will never get. Run claude --version to check you’re on the latest build, then /login. The Claude Code CLI documentation covers --resume and --continue if a run died mid-task.
Proxy or DNS failure. Corporate proxies, VPNs and slow DNS all look the same at startup: the spinner runs and nothing happens. Set HTTPS_PROXY explicitly, or run curl https://api.anthropic.com from the same shell to test the network path.
Why does Claude Code show 0 tokens and stop responding?
Zero tokens means nothing has come back since the counter last moved. Either the API refused the request, or the stream died mid-response.
Rate limits and overloaded errors. Claude Code retries these, so it looks busy while it’s really waiting to try again. If 0 tokens follows heavy use earlier in the day, a limit is the likely cause, and a few minutes’ wait often clears it. Anthropic’s rate limit documentation explains how the limits work.
A stream cut mid-response. The connection drops halfway through a long reply and the client keeps waiting, showing 0 new tokens indefinitely. Press Esc and resend the last prompt.
Exit·0 can’t see a frozen counter. But if Claude gives up on a rate limit or an overloaded error, the run stops and you get CRASHED. NOT YOUR FAULT. with the reason in plain words.
How do I tell a permission wait from a retry loop?
Both look like a spinner and no output. The transcript tells them apart.
| signal | permission wait | retry loop |
|---|---|---|
| transcript | a question waiting for approval | the same error or “retrying” text, repeating |
| tokens | frozen | flat, but timestamps keep ticking |
| fix | answer the prompt | wait out the overload, or restart |
A permission wait means the session is waiting on you, not broken. Look for “Allow npm install?” or a tool approval line. It’s the most common reason a run “does nothing for nineteen minutes” after you switch windows. For a retry loop, check Anthropic’s status page before blaming your session.
Exit·0 hears Claude Code’s hooks, so it tells you when a session is waiting on a permission prompt (NEEDS YOU), and when one stops on an API error (CRASHED). A retry loop or a slow think fires no hook, so Exit·0 stays quiet for both. How it was made explains why it’s built on hooks.
What network or auth issues cause a hang mid-run?
An expired token. OAuth tokens can lapse during a long run. The process looks alive but every request bounces. Log in again in a fresh window, then restart the stuck session rather than waiting for it to recover.
A proxy or VPN dropping the connection. Same symptom: the spinner runs and nothing streams. Run a plain curl to the API from another terminal. If that hangs too, it’s the network, not the model.
Exit·0 can’t see a dropped connection either. If Claude does give up with a login error, you get CRASHED with “logged out” instead of silence. The hook-script comparison covers what Exit·0 hears and where a plain hook falls short.
Which fixes should you try first?
- Esc, then re-prompt. A session “thinking” with no token movement is often mid-turn on a request that will never resolve. Esc discards that turn, not the conversation, so you keep your context and file changes.
- Ctrl+C, then
claude --resume. If Esc does nothing, end the run and reload the session from disk. - Update the CLI. If the same hang keeps coming back, a specific version may be the cause. Check the changelog, then update or pin back via npm.
Is it stuck, or just thinking slowly?
You can’t always tell, and the answer is in change over time. A twenty to sixty minute run is normal: tokens ticking up, tool calls appearing and a changing spinner verb all mean it’s alive. A stuck session is still: 0 tokens for several minutes, the same spinner verb, no new lines.
The rule: if nothing has changed across two checks a few minutes apart, go and look. If something moved, go back to your coffee.
How do I recover a session without losing work?
Claude Code writes the session to disk as it goes. claude --resume lists recent sessions so you can pick the one that froze, and claude --continue reopens the latest one in that directory. The plan, edited files and history come back with it.
Before you kill anything, read the last line of output. A permission prompt isn’t a crash, and killing the process mid-install or mid-edit can leave a file half-written. If it’s a question, answer it. If tokens have sat at 0 for several minutes with no error, kill it and resume.
How do you notice a stuck session when you’re away?
You can’t, unless something tells you. A sound is half an answer with four terminals open and one sitting on “Allow npm install?” for fifteen minutes. You need to know which session, and whether it finished, broke or is waiting on you.
That’s what Exit·0 does. It’s a small pixel machine in your Mac menu bar that tells you, per session, when Claude Code finishes, breaks or needs you, and when Claude itself crashes on an API error. Walk away from the Mac and your iPhone gets it instead. Go make a tea. It’ll tell you.
Where it falls short: it hears hooks, so a session that hangs without stopping or asking sends nothing. For that one, the two-checks rule still applies.
FAQ
Does restarting Claude Code lose my conversation?
No. Sessions are written to disk as they run. claude --resume picks the frozen session from a list, and claude --continue reopens the most recent one in that directory.
Why does it hang at 0 tokens when Anthropic’s status page is green?
The status page covers Anthropic-wide incidents, not your connection. An expired token, a proxy or VPN dropping the connection, or a stream that died mid-reply all give 0 tokens with no outage. A plain curl to the API from another terminal tells you which side it’s on.
Is stuck thinking the same as being rate limited?
Not always, though they look alike. A rate limit repeats “retrying” text at regular intervals. A genuine stall produces no output at all.
How do I stop missing permission prompts?
You can’t skip them, since approvals are part of how Claude Code stays safe. You can notice them sooner: scroll for an unanswered question before assuming a crash, or let Exit·0 tell you with NEEDS YOU.