Repository navigation
Description
Summary
When the model used for /compact returns a response containing only reasoning parts and no text part, opencode lands that empty-body message as the session summary and reports compact as successful. The epoch replacement then permanently destroys the original conversation history — yet everything reports success, so the agent continues with an essentially empty (corrupted) context and no warning.
Reproduction — 100% reproducible (2/2 triggers)
- opencode v1.18.21 (latest)
- Model:
opencode-go/glm-5.3(reasoning model) - Triggered compaction twice on this model; both times compact reported success while the summary message had only a
reasoningpart and notextpart, and the original history was lost.
Steps:
- Use
opencode-go/glm-5.3in a session. - Trigger
/compact. - Compact reports success; the resulting summary message has no text body; the original history is gone and cannot be recovered.
Relationship to #41571
Shares the same core failure as #41571 (Kimi K3-256k): a reasoning model produces a reasoning-only summary (no text part), opencode marks it summary: true, lands it, and swaps in an empty summary — silently dropping history. #41571 traces this to the v1.18.15 serialize() flattening change in compaction.ts (history flattened to a wall of plain text → reasoning model analyzes instead of summarizing). opencode-go/glm-5.3 on v1.18.21 exhibits the identical symptom at a 100% rate, suggesting the serialize-format issue affects reasoning models broadly, not just k3-256k. (I have not yet read compaction.ts to confirm glm-5.3's exact trigger mechanism, but the symptom + 100% rate + reasoning-model + same serialize code path make a shared root cause highly likely.)
Additional proposals
- L0 (stream layer): detect/reject reasoning-only (no-text-part) responses as incomplete at stream end — upstream defense before compaction even runs.
- Structural detection basis: per the
@opencode-ai/sdkPart union,TextPart(type:"text") andReasoningPart(type:"reasoning") are independent union members — a reasoning-only response has no text part at all and is structurally detectable, not a length-threshold heuristic (negligible false-positive risk). - Irrecoverability: once the epoch is replaced, the source material is destroyed, so any retry afterward is useless — the failure is silent and permanent. The failure must be caught before epoch replacement.
Expected behavior
- Compact should fail and retry the LLM while source material still exists when the produced summary has no non-empty
TextPart— not land it and replace the epoch. - The success/"compacted" marker must not be set until the summary passes body validation.
Suggested fix
Add a hasNonEmptyTextBody(message) check (iterate message.parts; require at least one type === "text" with non-whitespace content) at:
- L0 (stream layer): at stream end, reject reasoning-only responses as incomplete.
- L1 (compact landing): before epoch replacement, validate the summary body; on failure, retry the LLM (source still intact) instead of landing.
The same detection function can live in the SDK so plugins/tools share one definition. This is the "at minimum detect empty summaries and fail" bottom-line from #41571, plus an upstream L0 defense.
Impact
- Severity: high — irrecoverable, silent context loss; the agent continues on a broken session with no warning because the compacted flag is set despite no real content.
Environment
- opencode v1.18.21 (latest)
- Model:
opencode-go/glm-5.3(reasoning model) - Repro rate: 2/2 (100%)
Activity
github-actions commentedon Aug 22, 2026
This issue might be a duplicate of existing issues. Please check:
reasoningpart and notextpart, causing the summary to be empty and conversation history to be silently dropped. That issue also includes a detailed code-level root cause analysis and suggests the same fix (detect empty/text-less summaries and fail compaction instead of landing them)./compactfails with "Compaction produced no summary" for another reasoning-adjacent model (deepseek flash), same symptom of compaction silently producing no usable summary.If your issue is distinct (e.g., specific to stream interruption rather than the serialization format change), please clarify how it differs from #41571.
JeTSpice commentedon Sep 18, 2026
Edit: Looks like this is fixed in 1:18:31
Also experiencing this. Projects are needing to be restarted in a new session and context re-established.
Constantly getting this after compacting a session:
Error from provider (Console): OpenCode's free tier can only be used from within OpenCode.
pauldupuyjr commentedon Oct 2, 2026
This still reproduces on current dev (after v1.18.34), so it was not fixed in 1.18.31. With a reasoning model whose compaction output runs out on reasoning, or is cut off by the length limit, the empty or partial summary is accepted as the compaction boundary and the earlier history is dropped.
I have a fix with regression tests that re-derives the guard from #42063 (closed for age, not rejected) and also rejects summaries cut off by
finish: "length". Opening it as a PR now; happy to adjust if @rekram1-node already has this in progress.LegendaryFire commentedon Oct 5, 2026
This is an issue I'm also running into with OpenCode v2.0.22, however has happened for a few versions already. #53242
thdxr commentedon Oct 11, 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 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊