Alongside my own work as an indie developer, I run a pipeline that drafts content for several sites through the Claude API, every day. Keeping Claude running for long stretches like that, I hit "no response" and "it froze halfway" situations constantly. Early on, I'd reload blindly each time, without splitting the causes apart first.
But there are only a handful of causes, and once you know how to tell them apart, the fix is quick. The thing that matters most is not confusing "this will resolve if I wait" with "this will never resolve unless I fix it myself." Here's how I split it.
First, Figure Out Where It's Stuck
It's tempting to lump everything under "no response," but the fix changes completely depending on where it's stuck. Decide which situation you're in first.
- Using it in a browser or app (claude.ai or the desktop app) → waiting, reloading, or clearing cache usually fixes it
- Calling the API from your own code → you fix it in the code, with timeouts and retries
Confuse these two and you end up "restarting the browser over and over when you should be fixing code." Let's take them in turn.
Browser / App Side: The Order to Check
When the app in front of you isn't responding, working top to bottom triages it fastest.
1. Wait a few dozen seconds first. This is the most overlooked step. A short reply takes 10–30 seconds; loading a long answer or a large context can take a few minutes. If the progress indicator is moving, the work is almost certainly proceeding.
2. Open another site to check your connection. "It was just my network" happens more often than you'd think.
3. Reload the page. Temporary rendering glitches usually clear with this. Your conversation is saved, so nothing is lost.
4. Open an incognito window. If that fixes it, the cause is an extension. Ad blockers and script-control extensions sometimes stop the response from rendering.
5. Clear the cache. This is the last resort when the above don't help. Stale scripts can keep the screen from updating.
6. Check the status page. If nothing so far worked, it may be the service, not you. Check Anthropic Status for incidents.
It helps to know the peak hours, too. Running scheduled posting across several sites, what I feel concretely is that evenings in Japan (roughly 19:00–23:00) get congested, while early mornings (6:00–9:00) are noticeably lighter. Just shifting heavy work to a different hour changes how responsive it feels.
API Side: Why Code Stalls, and How to Fix It
When you're calling the Claude API from your own program and no response comes back, browser steps solve nothing. The cause almost always boils down to one of three things.
The timeout is too short
Long contexts and complex reasoning take time to answer. If your HTTP client's default timeout is short, your code gives up while generation is still in progress. Set the SDK timeout explicitly higher.
import anthropic
# Set a longer-than-default timeout
client = anthropic.Anthropic(timeout=120.0)
response = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=4096,
messages=[{"role": "user", "content": "Please summarize this long text ..."}],
)What looked like "it's frozen" was actually me cutting it off with my own timeout — that was my first mistake.
Long replies make the wait unpredictable
The longer the reply, the longer you wait for the final character. To tell whether it truly stalled or is still generating, streaming helps. Whether tokens are flowing tells you instantly if it's alive.
with client.messages.stream(
model="claude-sonnet-4-6",
max_tokens=4096,
messages=[{"role": "user", "content": "Please explain in detail ..."}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)No characters flowing means a connection-side problem; characters flowing means it's just long.
The tricky case is when tokens flow at first and then stop dead midway. The connection itself is alive but no data arrives — a state the overall timeout alone can't reliably catch. Watch the time since the last token with a separate timer, and close the stream when it goes quiet, and you cut off this "silent hang" early.
import threading
import anthropic
client = anthropic.Anthropic(timeout=120.0)
def stream_with_idle_watchdog(messages, idle_limit=30.0):
"""Close the stream if nothing arrives for idle_limit seconds."""
chunks = []
with client.messages.stream(
model="claude-sonnet-4-6",
max_tokens=4096,
messages=messages,
) as stream:
def on_idle():
stream.close() # unblocks the stalled iteration
timer = threading.Timer(idle_limit, on_idle)
timer.start()
try:
for text in stream.text_stream:
timer.cancel()
chunks.append(text)
timer = threading.Timer(idle_limit, on_idle)
timer.start()
finally:
timer.cancel()
return "".join(chunks)Where the overall timeout catches "generation is taking too long," this idle watch catches "the flow was cut off." They play different roles, so keeping both lets you hand the "is it stuck or should I wait?" judgment off to the machine. In my own pipeline, the occasional mid-stream stall during overnight batches became almost hands-off once I had this two-layer guard.
You're not retrying transient errors
A 429 (rate limit) during congestion or a server-side 5xx usually goes through if you wait a moment and resend. By contrast, 400-class errors (a malformed request) will never go through no matter how many times you send, so you should stop immediately and fix the cause. Building in this distinction makes most "it looks stuck" cases resolve on their own.
import time
import anthropic
client = anthropic.Anthropic(timeout=120.0)
def create_with_retry(**kwargs):
for attempt in range(4):
try:
return client.messages.create(**kwargs)
except anthropic.RateLimitError:
time.sleep(2 ** attempt) # back off: 1, 2, 4, 8 seconds
except anthropic.InternalServerError:
time.sleep(2 ** attempt)
except anthropic.BadRequestError:
raise # 400-class: don't retry, stop right away
raise RuntimeError("retry limit reached")My pipeline still throws the occasional 429 when I batch jobs overnight. Since adding this exponential backoff, I almost never rerun anything by hand.
"Wait" or "Fix" — A Quick Reference
When in doubt, decide by this:
- Progress moving / tokens flowing → wait (it's normal)
- Browser frozen, extensions installed → reload / check in incognito
- Your code always cuts off after a fixed time → raise the timeout
- Intermittent failures during busy hours → add retry with backoff
- A
400-class error returns → waiting won't help; fix the request
Next Step
If you're calling the API from your own code, today just add an explicit timeout and exponential backoff for 429 and 5xx. Those two alone make most of the "it stalled" moments quietly disappear.
I was the guy mashing reload at first, too. If it trims even a little off the same detour for you, I'll be glad.