Context Overflow and Streaming Disconnects: A Prevention Checklist
Both failures share a root cause: something that was fine at the start of a request outlived the resources allocated to it. A conversation grows past the model's context window, or a streaming connection drops mid-response. This checklist covers the concrete steps to prevent both, and to recover cleanly when prevention isn't enough.
How to Use This Checklist
- Work through the two tiers in order: context management first, streaming resilience second, they compound in agentic loops that stream long tool-using conversations.
- Treat items 1-4 as required for any multi-turn or agentic Claude integration; items 5-8 apply once you've confirmed context is under control.
- Items 9-14 apply specifically to any code using the SDK's streaming API; skip them if you only use non-streaming calls.
- Revisit this checklist whenever you add a new tool to an agent loop, since tool results are a common source of unplanned context growth.
- Record the token count and turn count at which any failure occurred, that number tells you how much headroom you actually need to trim to.
Context Overflow Prevention (1-8)
- Know your model's actual context window before you build against it. Look up the current context window for the specific model you're calling, don't assume it matches an older model's limit from memory.
- Count tokens per turn, not just per request. Use the SDK's token counting to measure the running total of a conversation after each turn, not just the size of the latest message.
- Set a trim threshold well below the hard limit. Reserve headroom, commonly 15-25% of the window, for the model's own response and any tool results still to come in the same turn.
- Summarize or drop the oldest turns before truncating mid-message. Truncating a message in the middle can leave a
tool_useblock without its matchingtool_result, which the API will reject outright. - Cap tool result size before it re-enters context. A tool that can return an unbounded amount of data (a full file, a large query result) needs its own truncation or summarization before being appended back into the conversation.
- Persist full history outside the context window, not inside it. Keep a complete transcript in your own storage, and only feed the model a trimmed working window, so trimming for the API never means losing data for your own logs or a later human review.
- Test with a conversation long enough to actually hit your trim threshold. A short test conversation will never exercise trimming logic; deliberately construct a long one in a test to confirm the threshold triggers correctly.
- Alert on approaching context limits, not just on overflow. A warning at 80% of your trim threshold gives you time to investigate a conversation that's growing unusually fast, before it actually fails.
Streaming Disconnect Recovery (9-14)
- Track partial output as it streams, not just at completion. Buffer text deltas as they arrive so a mid-stream disconnect leaves you with whatever was already generated, not nothing.
- Distinguish a clean stream end from a dropped connection. A stream that ends with a proper
message_stopevent succeeded; a stream that raises a connection error partway through did not, and needs different handling. - Set a reconnect policy for dropped streams, using the same backoff discipline as any other transient failure. A raw retry on a dropped stream should follow the same jittered backoff approach as any other transient Claude API failure, not a separate ad hoc loop.
- Decide up front whether a reconnect resumes or restarts. The Messages API does not resume a partially-streamed response from where it left off; a reconnect issues a new request, so decide whether to re-send the full prompt or continue from the partial output you already buffered.
- Chunk large outputs for the consumer, independent of how the model streams them. If your own downstream consumer (a UI, another service) can't handle an unbounded stream, chunk what you forward to it regardless of how Claude delivers tokens.
- Log the byte/token count actually delivered before a disconnect. This number is what tells you, after the fact, whether the reader saw a nearly-complete response or almost nothing, which changes whether the right recovery is "just show what we have" or "restart cleanly."
import anthropic
client = anthropic.Anthropic()
def stream_with_recovery(prompt: str) -> str:
collected = ""
try:
with client.messages.stream(
model="claude-sonnet-5",
max_tokens=1024,
messages=[{"role": "user", "content": prompt}],
) as stream:
for text in stream.text_stream:
collected += text
return collected
except anthropic.APIConnectionError:
# Partial output is preserved in `collected` even though the
# stream dropped; the caller decides whether to show it or retry.
return collectedApplying the Checklist in Order
- Context items (1-8) come first because an overflowing context can itself cause a streamed response to be cut short mid-generation, a lifecycle failure masquerading as a streaming failure.
- Streaming items (9-14) assume context is already under control, so a disconnect you're debugging is genuinely a connection issue, not a symptom of an oversized request.
- Revisit both tiers together after any change to tool definitions, since new tools are the most common source of both context growth and larger streamed outputs.
Gotchas
- Trimming mid-message instead of mid-turn. Cutting a message in the middle of a
tool_use/tool_resultpair produces an invalid conversation the API will reject. Always trim at turn boundaries. - Assuming a dropped stream can resume from where it left off. It can't; a reconnect is a new request, and your code needs to explicitly decide whether to restart or continue from buffered partial output.
- No alerting until the hard failure. Waiting for an actual context-overflow error to notice a conversation is growing too large means you find out from a user-facing failure, not a dashboard.
FAQs
How much headroom should I reserve below the hard context limit?
A common starting point is 15-25% of the window, enough to cover the model's own response plus any tool results still expected in the same turn. Tune this based on how large your typical tool results actually are.
Why can't I just truncate the oldest message when a conversation gets long?
If the truncated message is a tool_use block, its matching tool_result further along in the conversation becomes orphaned, and the API will reject the resulting message sequence. Trim whole turns, not arbitrary message fragments.
Does the Claude API support resuming a dropped stream from where it stopped?
No. A reconnect after a dropped stream is a new request. Your code has to explicitly decide whether to resend the original prompt or continue the conversation using whatever partial output you already buffered.
Should I persist full conversation history even if I trim what I send to the model?
Yes. Keep the complete transcript in your own storage and only send a trimmed working window to the API. That way, trimming for context-window reasons never means losing data for your own logs, audits, or a later human review.
What's the difference between a stream ending cleanly and a stream disconnecting?
A clean end delivers a proper stop event after the model finishes generating. A disconnect raises a connection error partway through, before that stop event arrives, and needs explicit recovery handling rather than being treated as a normal completion.
How do I know if a tool is at risk of causing context overflow?
Any tool whose output size isn't bounded, a file read, a search result set, a database query, is a candidate. Cap or summarize its output before it's appended back into the conversation, rather than assuming it will always be small.
Is reconnecting to a dropped stream the same as retrying a failed non-streaming call?
The backoff discipline should be the same (jittered exponential backoff), but the decision of what to send on reconnect is different: a non-streaming retry usually resends the same request unchanged, while a stream reconnect has to decide whether to resend the full prompt or continue from partial output.
Should I alert only when context overflow actually happens, or earlier?
Earlier. Alert at a threshold below your trim point (e.g. 80% of it) so you have time to investigate why a specific conversation is growing unusually fast, rather than only finding out once trimming or an outright failure has already occurred.
How do I test that my trimming logic actually works?
Deliberately construct a long test conversation that exceeds your trim threshold and assert that trimming triggers at the expected point. A short conversation in a typical test suite will never exercise this path.
Does chunking output for my own UI matter if Claude already streams token by token?
Yes, they're independent concerns. Claude's token-level streaming doesn't guarantee your downstream consumer, a browser, a mobile client, another service, can handle an unbounded or unchunked stream; chunk what you forward based on what that consumer actually needs.
What should I log when a stream disconnects partway through?
The amount of output already delivered (token or byte count) before the disconnect. That number tells you whether the user saw a nearly-complete response worth keeping, or almost nothing, which changes whether the right recovery is to show the partial output or discard it and retry.
Is context overflow more likely in agentic tool-use loops than simple chat?
Yes. Each tool call and its result adds to the running context, and agentic loops often run many turns in a row without a natural pause, so context can grow faster and less predictably than in a straightforward back-and-forth chat.
Related
- Understanding Why Claude Agents Fail in Production - where lifecycle failures fit in the broader failure taxonomy.
- Troubleshooting & Reliability Basics - the logging foundation this checklist assumes is already in place.
- Retry and Exponential Backoff Strategies for Transient Claude API Failures - the backoff discipline to apply when reconnecting a dropped stream.
- Prompt Cache Miss Storms: Diagnosing Sudden Cost and Latency Spikes - how context trimming choices can also affect cache stability.
- Troubleshooting & Reliability Best Practices - where this checklist fits into the broader set of practices.
Stack versions: Written against the Claude model lineup current as of ~June 2026 - Claude Fable 5, Claude Opus 4.8, Claude Sonnet 5 (the default), and Claude Haiku 4.5 - and the official
anthropicPython SDK (latest 0.x release). Model names, pricing, and SDK versions move quickly - verify current specifics at platform.claude.com/docs before relying on them.