Claude Streaming Not Working Fix

Written by Michael Lip · Solo founder of Zovo · $400K+ on Upwork · 100% JSS Join 50+ builders · More at zovo.one

Streaming lets you receive Claude’s response incrementally via Server-Sent Events (SSE), but connection drops, missing events, and incorrect event handling can make it seem broken. This guide covers every common streaming failure.

The Error

When streaming is not set up correctly, you may see:

anthropic.APITimeoutError: Request timed out.

Or the stream opens but no text appears because your code does not handle the correct event types.

When using streaming via SSE, it is possible for an error to occur after the server returns a 200 response code.

Quick Fix

  1. Use the SDK streaming helpers (stream() in Python, .stream() in TypeScript) instead of raw stream=True.
  2. For long requests, increase the timeout or use streaming to avoid the SDK’s 10-minute timeout.
  3. Handle APIError exceptions even inside streaming blocks – errors can arrive mid-stream.

What Causes This

Streaming fails or appears broken when:

Full Solution

Python: Use the Stream Helper

The simplest way to stream in Python. The stream() context manager handles all event types:

import anthropic

client = anthropic.Anthropic()

with client.messages.stream(
    model="claude-sonnet-4-6",
    max_tokens=4096,
    messages=[{"role": "user", "content": "Write a detailed essay about climate change"}]
) as stream:
    for text in stream.text_stream:
        print(text, end="", flush=True)

# Get the complete message after streaming finishes
message = stream.get_final_message()
print(f"\nTokens used: {message.usage.input_tokens} in, {message.usage.output_tokens} out")

TypeScript: Use the Stream Helper

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

const stream = client.messages.stream({
  model: "claude-sonnet-4-6",
  max_tokens: 4096,
  messages: [{ role: "user", content: "Write a detailed essay" }]
}).on("text", (text) => {
  process.stdout.write(text);
});

const message = await stream.finalMessage();
console.log(`\nTokens: ${message.usage.input_tokens} in, ${message.usage.output_tokens} out`);

Python: Raw Event Streaming

If you need access to individual SSE events:

import anthropic

client = anthropic.Anthropic()

stream = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1024,
    stream=True,
    messages=[{"role": "user", "content": "Hello"}]
)

for event in stream:
    if event.type == "content_block_delta":
        if event.delta.type == "text_delta":
            print(event.delta.text, end="", flush=True)
    elif event.type == "message_stop":
        print("\n[Stream complete]")
    elif event.type == "error":
        print(f"\n[Error: {event.error}]")

Handle Mid-Stream Errors

Errors can arrive after a 200 response when streaming. Always wrap streams in try/except:

import anthropic

client = anthropic.Anthropic()

try:
    with client.messages.stream(
        model="claude-sonnet-4-6",
        max_tokens=4096,
        messages=[{"role": "user", "content": "Write a long response"}]
    ) as stream:
        collected_text = ""
        for text in stream.text_stream:
            collected_text += text
            print(text, end="", flush=True)
except anthropic.APIError as e:
    print(f"\nStream error: {e.status_code} - {e.message}")
    # collected_text contains partial response up to the error

Fix the 10-Minute Timeout

The SDK throws ValueError if a non-streaming request is expected to exceed 10 minutes. Use streaming with get_final_message() to get the complete message without writing event-handling code:

import anthropic

client = anthropic.Anthropic()

# Instead of a non-streaming request that might time out:
with client.messages.stream(
    model="claude-opus-4-6",
    max_tokens=128000,
    messages=[{"role": "user", "content": "Write a very long document"}]
) as stream:
    message = stream.get_final_message()

# message is a complete Message object, same as non-streaming
print(message.content[0].text)

TypeScript Equivalent

import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

const stream = client.messages.stream({
  model: "claude-opus-4-6",
  max_tokens: 128000,
  messages: [{ role: "user", content: "Write a very long document" }]
});

const message = await stream.finalMessage();
console.log(message.content[0].type === "text" ? message.content[0].text : "");

Async Streaming (Python)

from anthropic import AsyncAnthropic

client = AsyncAnthropic()

async with client.messages.stream(
    model="claude-sonnet-4-6",
    max_tokens=4096,
    messages=[{"role": "user", "content": "Hello"}]
) as stream:
    async for text in stream.text_stream:
        print(text, end="", flush=True)

Prevention

  1. Always use streaming helpers: stream() + text_stream in Python, .stream() + .on("text") in TypeScript. They handle all event types correctly.
  2. Use streaming for long outputs: Any request with max_tokens > 4096 should use streaming to avoid timeout issues.
  3. Wrap streams in error handling: Mid-stream errors are possible. Always use try/except around stream iteration.
  4. Use get_final_message() / finalMessage(): When you do not need real-time output but want to avoid the 10-minute timeout, these methods give you the complete message object.