Repository navigation
Description
Summary
Compaction fails with a misleading "Compaction summary reached the output token limit" banner followed by the raw provider error (exceed_context_size_error: request (8588 tokens) exceeds the available context size (8192 tokens), try increasing it) when the compaction summary request is larger than the provider's actual context window. No output token limit was hit — the request simply did not fit the served context. The message hides the real problem (model context too small / mismatch between configured and served limits), and compaction cannot proceed.
Environment
- opencode version: 1.14.42
- OS: Windows 11 Pro 10.0.26200 (x64)
- Terminal: xterm-256color (PowerShell)
- Shell: C:\WINDOWS\system32\cmd.exe (ComSpec)
- Install/channel: npm global install (latest)
- Active plugins: none found in config
Reproduction
-
Use a provider whose served context window is smaller than the context limit opencode thinks the model has. For example: LM Studio (OpenAI-compatible) serving a model with
n_ctx_slot = 8192, while opencode config declareslimit.context: 65536for the same model. -
Use the model until the session exceeds the server's real context (e.g. 8K tokens).
-
Trigger compaction (auto, on overflow, or manual).
-
Observe the result: the compaction summary finishes with an error; the UI shows:
Compaction summary reached the output token limit exceed_context_size_error: request (8588 tokens) exceeds the available context size (8192 tokens), try increasing itThe server log shows the same overflow on every retry (e.g.
request (22254 tokens) exceeds the available context size (8192 tokens), try increasing it).
Expected Behavior
One of:
- The compaction summary request should be sized to fit the provider's actual context window (it is currently sized against the configured limit, so a stale/overstated
limit.contextguarantees overflow), or - The server's real context should be taken into account (e.g. fetched/advertised caps), or
- At minimum, the error surfaced to the user should be clear and actionable — e.g. "The model's context window (8192 tokens) is too small to compact this conversation. Increase the context size or start a new session." — instead of the misleading "reached the output token limit" message.
The current wording is actively harmful: it points at output-token limits and suggests increasing them, when the actual cause is that the request exceeds the available input context.
Actual Behavior
The compaction summary request is sent as-is once the configured budget allows it. When the provider rejects it with exceed_context_size_error, the user sees the "Compaction summary reached the output token limit" banner plus the raw provider error. Compaction fails and the running session cannot be compacted until the model is reloaded with a bigger context or the config is fixed.
Additional Context
- Root cause observed locally: LM Studio server log line:
srv load_model: initializing, n_slots = 4, n_ctx_slot = 8192, kv_unified = 'true', immediately followed by overflow errors on requests around 8-22K tokens. - Trigger scenario: the user reinstalled opencode (config reset) and LM Studio's
defaultContextLengthwas reset to its 8192 default while the opencode config still declaredlimit.context: 65536. The mismatch between the configured limit and the served context is what makes this occur. This is a plausible scenario for anyone with a stale config vs. a changed local server. - Workaround: align
limit.contextin opencode config with the provider's real context size and restart both sides (confirmed working). - Note: in the current dev branch (
packages/core/src/session/compaction.ts), a guard was added —if (Token.estimate(summaryPrompt) > context - summaryOutput) return false— so compaction skips instead of sending an oversized request. However it still sizes against the configured context, so the mismatch case (configured > served) can still slip through and produce the misleading error.
Activity
pm25coder commentedon Sep 21, 2026
Confirmed and extended — I traced both gates in
packages/core/src/session/compaction.tsonmainand ran the arithmetic locally.Both gates size against the configured limit, so neither can fire here
compactAfterOverflowtakes the window from the configured limits only (compaction.ts:179) and then guards the prompt it just built:compactIfNeededreads the same number (compaction.ts:234) before handing off (compaction.ts:242). With your config —limit.context: 65536, an LM Studio slot of 8192,generation.maxTokensunset —outputfalls back to0(compaction.ts:181, 236), so:DEFAULT_BUFFER = 20000)SUMMARY_OUTPUT_TOKENS = 4096)I ported the two functions verbatim and ran them under node 22, reading the constants out of the tree rather than retyping them:
So with a stale
limit.contextthe guard never gets a chance to refuse before the provider does. Two details in that arithmetic are worth naming:summaryOutput = min(output || 4096, 4096)for output (compaction.ts:189, 208) — half of an 8192-token window — yet the guard subtracts it from the configured 65536. It starts from roughly 15× the input budget that actually exists.Token.estimateisround(length / 4)over the JS string (util/token.ts:5), applied to the serialized transcript, not to provider tokens.Why the raw provider error arrives with nothing around it
In
packages/core/src/session/runner/llm.ts,recoverOverflowis wired to this very function (compaction.compactAfterOverflow, llm.ts:377), and the retry is taken only when the failure classifies as an overflow (llm.ts:292). When the summary stream itself errors,compactAfterOverflowsetsfailed = true(compaction.ts:213) and returns a plainfalse(compaction.ts:221) — after which the runner republishes the original provider error verbatim (if (overflowFailure) yield* publish(overflowFailure), llm.ts:296). The return value is a bare boolean, so no caller can tell "there was no head left to summarize" apart from "the summary request overflowed as well". That is the mechanical reason a user seesexceed_context_size_errorwith no explanation attached.The information your expected message needs is already on the event
The repo's own classifier already matches your strings (
packages/llm/src/provider-error.ts:18). I ran the pattern list from that file over the messages in your report:So the overflow is recognised, the event carrying it is in hand at llm.ts:296, and its message already contains both numbers. Printing your suggested sentence needs no new plumbing — the wording path just has to stop treating this case as an output-token problem.
Suggested order of fixes
compactAfterOverflowinstead offalse(e.g.no-head/summary-too-large/summary-failed), so the runner can say "the model's window (8192 tokens) is too small to compact this conversation — raise it or start a new session".min(configured, observed)minussummaryOutput, and clampsummaryOutputto a fraction of that window instead ofmin(output || 4096, 4096)against a window it never checked. The cap quoted in this very error is enough to seed a per-model cache.Scope note: this is source reading plus a local harness porting the two functions and the classifier — I had no LM Studio server to drive, so treat the multiples above as gate arithmetic, not as a replay of your session.
One loose end: I could not find that banner string anywhere. It is not in the tree on
main, and it is not in the build you are running either — I unpackedopencode-windows-x64@1.14.42(the platform package behind theopencode-aiwrapper) and searched the 158,887,816-byte binary; the compaction strings it ships are the" Compaction "/" Auto Compaction "box titles and the twoContextOverflowErrormessages ("Conversation history too large to compact - exceeds model context limit" and "Session too large to compact - context exceeds model limit even after stripping media"). If you still see that exact wording, it is worth pinning which build produced it — the sizing defect above is independent of it.Tarquinen commentedon Oct 20, 2026
Thanks for the report! OpenCode 2.0 is now out and development is focused on V2, so we're closing issues filed against OpenCode 1. Please upgrade (
opencode upgrade --major, details: https://anoma.ly/notes/opencode-2-0), and if this is still relevant on 2.0, reopen this issue or open a new one with your 2.0 version.— from 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊