sipeed/picoclaw · error
context window still exceeded after retry compaction; refusi
Error message
context window still exceeded after retry compaction; refusing to drop active turn messages: %w
What it means
Thrown in the LLM retry loop (pipeline_llm.go) after a context-compaction rebuild was attempted and the message history STILL does not fit the context budget. The library deliberately refuses to shrink further because that would require dropping messages from the active turn (protectedTurnTail), which would corrupt in-flight conversation state; it wraps the original fit error instead.
Source
Thrown at pkg/agent/pipeline_llm.go:443
"retry": retry,
"dropped_msgs": dropped,
"remaining_msgs": len(exec.history),
"context_window": ts.agent.ContextWindow,
"max_tokens": ts.agent.MaxTokens,
"still_overlimit": !fit,
})
} else if !fit {
logger.WarnCF("agent", "Context still exceeds budget after retry compaction rebuild", map[string]any{
"session_key": ts.sessionKey,
"retry": retry,
"history_msgs": len(exec.history),
"protected_turn_msgs": len(protectedTurnTail),
"context_window": ts.agent.ContextWindow,
"max_tokens": ts.agent.MaxTokens,
})
}
if !fit {
err = fmt.Errorf(
"context window still exceeded after retry compaction; refusing to drop active turn messages: %w",
err,
)
break
}
continue
}
break
}
if err != nil {
al.emitEvent(
runtimeevents.KindAgentError,
ts.eventMeta("runTurn", "turn.error"),
ErrorPayload{
Stage: "llm",
Message: err.Error(),
},View on GitHub (pinned to 49183d7e8d)
Solutions
- Increase the agent's ContextWindow (or move to a larger-context model) so the active turn + compacted history fits
- Reduce the size of current-turn tool outputs: truncate/limit tool results before they enter history
- Start a new session or clear history so the compacted baseline is smaller
- Verify MaxTokens leaves headroom — it consumes part of the window budget
Example fix
# before
agents:
defaults:
model: llama-3-8k-text # tiny window, huge tool outputs
# after
agents:
defaults:
model: gpt-4o # 128k window
max_tokens: 4096 Defensive patterns
Strategy: validation
Validate before calling
func estimateTokens(msgs []providers.Message) int {
n := 0
for _, m := range msgs {
n += len(m.Content) / 4 // rough chars-per-token heuristic
}
return n
}
// before the turn: refuse to send if the active turn alone cannot fit
if estimateTokens(exec.messages) > ts.agent.ContextWindow-ts.agent.MaxTokens {
return fmt.Errorf("history too large for window %d; trim tool outputs or widen window", ts.agent.ContextWindow)
} Type guard
func isContextOverflowError(err error) bool {
return err != nil && strings.Contains(err.Error(), "context window still exceeded")
} Try / catch
if err := runTurn(); isContextOverflowError(err) {
// recover by starting a fresh session or widening the window, then retry
session.Reset()
widenContextWindow(agent)
return runTurn()
} Prevention
- Truncate large tool outputs before they enter history
- Choose models with context windows comfortably above worst-case turn size
- Keep MaxTokens well below ContextWindow to leave room for history
When it happens
Trigger: agent.ContextWindow/MaxTokens too small for: protected active-turn messages (large tool outputs, huge pasted files) + compacted history. Compaction already trimmed what it could (logged via 'Context still exceeds budget after retry compaction rebuild'), the fit check fails again, and the loop aborts with this error.
Common situations: Huge tool results (file reads, command dumps) inside the current turn; a small-window model (7k-8k) assigned to an agent with verbose tools; long sessions whose compacted summary plus turn tail still exceed the window; MaxTokens set close to ContextWindow leaving no room for history.
Related errors
- fallback model %q has no active provider
- feishu channel is not supported on 32-bit architectures (arm
- must be in range 1-65535
- create request: %w
- failed to load config: %w
AI-assisted analysis of sipeed/picoclaw@49183d7e8d (2026-08-15).
Data as JSON: /api/errors/e8fb714820b2c36c.
Report an issue: GitHub.