OpenAI Context Length Exceeded — Fix (2026) | AI Error Hub
OpenAIRate LimitsSeverity: HighHTTP 400

OpenAI Context Length Exceeded

Your messages tokens plus max_tokens (or max_completion_tokens on o-series) exceeds the model's context window. Fix by trimming history, summarizing older turns, chunking documents, or moving to a model with a larger window.

Error code: context_length_exceededHTTP: 400Category: ContextLast tested: Nov 15, 2026
Quick Fix (TL;DR)

Count your prompt tokens with tiktoken. Ensure input_tokens + max_tokens ≤ model_context. GPT-5: 400K context. GPT-4o: 128K. o3: 200K. If over, trim old conversation turns, summarize with a cheaper model, or split documents into chunks.

The Error Message You're Seeing

Response body
HTTP/1.1 400 Bad Request

{
  "error": {
    "message": "This model's maximum context length is 128000 
    tokens. However, your messages resulted in 132000 tokens 
    (128500 in the messages, 3500 in the completion). 
    Please reduce the length of the messages or completion.",
    "type": "invalid_request_error",
    "code": "context_length_exceeded"
  }
}

Model Context Windows Reference

ModelContext windowMax output
gpt-5400,000128,000
gpt-5-mini400,000128,000
gpt-4o128,00016,384
gpt-4o-mini128,00016,384
o3200,000100,000
o3-mini200,000100,000
o1200,000100,000

What Actually Causes This Error

40%
Growing conversation historyEach turn appended; no trimming; eventually overflows.
25%
Large document dumps in system promptFull RAG results stuffed into context without ranking.
18%
max_tokens set too highModel window 128K, prompt 120K, max_tokens 16K — overflow by 8K.
10%
Vision inputs (images count as tokens)Each image = 85 tokens (low detail) up to ~1600 (high detail).
7%
Non-English inflates tokensUrdu, Arabic, Chinese use 2-3× more tokens than English.

Fixes That Work (Tested Nov 2026)

1Count Tokens Before Sending

Python · tiktoken pre-flight check
import tiktoken MODEL_LIMITS = { "gpt-5": {"ctx": 400_000, "encoding": "o200k_base"}, "gpt-4o": {"ctx": 128_000, "encoding": "o200k_base"}, "o3": {"ctx": 200_000, "encoding": "o200k_base"}, } def count_messages_tokens(messages, model): enc = tiktoken.get_encoding(MODEL_LIMITS[model]["encoding"]) total = 0 for msg in messages: total += 4 # per-message overhead for key, value in msg.items(): if isinstance(value, str): total += len(enc.encode(value)) return total + 2 # final priming def will_fit(messages, model, max_tokens): ctx = MODEL_LIMITS[model]["ctx"] prompt_tokens = count_messages_tokens(messages, model) return prompt_tokens + max_tokens <= ctx, prompt_tokens ok, count = will_fit(messages, "gpt-4o", 4096) if not ok: print(f"Would overflow: {count} + 4096 > 128000")

2Trim Old Turns with Priority

Python · sliding window with system pinned
def trim_to_fit(messages, model, max_tokens, safety=2000): """Keep system + newest messages; drop oldest until fits.""" ctx = MODEL_LIMITS[model]["ctx"] budget = ctx - max_tokens - safety # Always preserve system messages system_msgs = [m for m in messages if m["role"] == "system"] other = [m for m in messages if m["role"] != "system"] # Drop oldest until we fit while other and count_messages_tokens(system_msgs + other, model) > budget: other.pop(0) # drop oldest non-system return system_msgs + other # For conversations where user always asks in pairs, drop pairs def trim_pairs(messages, model, max_tokens): system_msgs = [m for m in messages if m["role"] == "system"] other = [m for m in messages if m["role"] != "system"] ctx = MODEL_LIMITS[model]["ctx"] budget = ctx - max_tokens - 2000 while other and count_messages_tokens(system_msgs + other, model) > budget: # Drop oldest user+assistant pair other = other[2:] if len(other) >= 2 else other[1:] return system_msgs + other

3Summarize Old Context

Python · summarization-based compression
def compress_history(messages, model="gpt-4o-mini"): """Replace oldest N turns with a summary.""" if len(messages) < 10: return messages system_msgs = [m for m in messages if m["role"] == "system"] convo = [m for m in messages if m["role"] != "system"] # Summarize first 60% of conversation split = int(len(convo) * 0.6) to_summarize, keep = convo[:split], convo[split:] summary = client.chat.completions.create( model=model, messages=[ {"role": "system", "content": "Summarize the following conversation preserving key facts, decisions, " "and open questions. Be concise. Max 500 words."}, *to_summarize ] ).choices[0].message.content return system_msgs + [ {"role": "assistant", "content": f"[Earlier conversation summary]: {summary}"} ] + keep
Compression preserves memory

Summarizing older turns with a cheap model (gpt-4o-mini) reduces context by 80%+ while keeping semantic memory. Refresh summary every N turns or when hitting 70% of context budget.

Preventing This Error Going Forward

  • Always count tokens before sending. tiktoken is fast and free.
  • Enforce budget: input + max_tokens ≤ ctx − 2K safety.
  • Trim conversations proactively. Don't wait for overflow.
  • Summarize instead of dropping. Cheaper model, preserves memory.
  • Choose model by context need. GPT-5 (400K) > o3 (200K) > GPT-4o (128K).
  • Vision: use low detail unless zoom needed. 85 vs 1600 tokens per image.
SK
Tested by Sana K.
Researcher · AI Error Hub
Last verified: Nov 15, 2026 · SDK: openai 1.54

Frequently Asked Questions

Yes — output tokens must fit inside the total window alongside prompt. If prompt is 120K and window is 128K, max_tokens can't exceed 8K.

Yes. o-series uses max_completion_tokens covering both reasoning tokens AND visible output. Prompt + max_completion_tokens ≤ context. Reasoning tokens can be 5-20K on hard problems.

Yes. Function schemas, descriptions, and past tool_calls in history all count. Large tool arrays (20+ tools) can consume 5-15K tokens before you even start.

Low detail: 85 tokens fixed. High detail: 85 + 170 per 512×512 tile. A 2048×2048 image at high detail = ~1,530 tokens.

No — cost scales with input tokens. Use the smallest model that fits your context. GPT-4o-mini at 128K is far cheaper than GPT-5 at 400K for the same content.