You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
reasoning: reasoning text missing entirely despite reasoning tokens (thinking never shown, no text leak) #54886
reasoning: reasoning text missing entirely despite reasoning tokens (thinking never shown, no text leak)
Summary
For a small but session-clustered set of assistant messages, opencode stores tokens.reasoning > 0 but the message contains no reasoning part at all —
and the stored text is clean (no inline chain-of-thought, no </think> tag).
Because there is no reasoning part, the TUI never shows a thinking block for
those turns, even though the model did think.
This is not the same as the inline-</think> leak (see Related): here the
reasoning content is absent from the message entirely rather than leaked into text.
Environment
opencode version: 2.0.27
OS: Windows (10.0.26200, x64)
Terminal: xterm-256color
Shell: cmd.exe
Install/channel: release
Active plugins: @firecrawl/opencode, opencode-tavily
Observed from the local session database (normally created sessions — not
imported/migrated).
Select opencode/big-pickle.
Send a handful of ordinary message turns.
In some sessions, every completed turn stores tokens.reasoning in the
~1090–1340 range, but the assistant message content contains only a single text part.
The TUI shows no thinking block for any of those turns.
Expected Behavior
When the provider reports reasoning tokens and delivers reasoning content, a reasoning part should be persisted on the message (and rendered as a
collapsible thinking block) — the same as when reasoning_content is returned.
Actual Behavior
The message has no reasoning part, and the text part does not contain the
chain-of-thought either. The reasoning content is simply not present anywhere in
the stored message.
Aggregate scan of the local session DB (all opencode/big-pickle assistant
messages):
bucket
count
tokens.reasoning > 0
2,754
— of those, contain a reasoning part
2,693
— of those, noreasoning part
61
— — of those 61, text contains a </think>/<think marker
0
The 61 affected messages are clustered by session (several affected turns
per session). One session had 6/6 completed turns affected, each with tokens.reasoning between 1,090 and 1,337 and content = ["text"] only.
Anonymized structure of one affected message (text content omitted):
The affected messages are structurally identical to normal ones (same finish, rawFinish, agent, model keys), so the trigger is not visible
at the message level.
Responses in affected sessions appear effectively non-streamed
(time.streamed ≈ time.completed), but that is also true of most messages
that do persist a reasoning part, so streaming alone does not explain it.
Workaround: start a new session — the large majority of sessions persist
reasoning correctly.
Thanks for the detailed report and the database scan. I was able to reproduce this on 2.0.27 with opencode/big-pickle.
I ran a series of one-shot turns (opencode run -m opencode/big-pickle "Write a short haiku about number N, thinking carefully first."), then scanned the local session database. On a fresh database, 4 of 24 assistant messages with tokens.reasoning > 0 had only a text part. Their reasoning token counts were 1174, 461, 380 and 61. Their text was clean, with no inline chain-of-thought or <think> tags. The other turns had a normal reasoning part. The script below runs the turns and the scan.
What I couldn't establish is where the reasoning gets lost. In the one turn I managed to capture on the wire, Zen streamed reasoning_content and OpenCode saved it correctly. I didn't capture an affected turn, so it's still open whether those responses contain reasoning that OpenCode drops or none at all. I also couldn't check the latest dev against this model, because Zen's free tier refuses requests from a source build. 2.0.27 is the latest release.
#!/usr/bin/env bash# Repro for #54886: run N one-shot turns with opencode/big-pickle (free Zen model),# then scan the local DB for assistant messages with tokens.reasoning > 0 but no reasoning part.# Usage: OC="opencode" ./repro.sh 15 (or OC="bun ... packages/cli/src/index.ts")set -u
N=${1:-15}
OC=${OC:-opencode}
mkdir -p /tmp/oc54886 &&cd /tmp/oc54886
foriin$(seq 1 "$N");do
timeout 150 $OC run --standalone -m opencode/big-pickle "Write a short haiku about number $((i+200)), thinking carefully first.">/dev/null 2>&1done
python3 - <<'PY'import sqlite3, json, osc = sqlite3.connect(os.path.expanduser('~/.local/share/opencode/opencode.db'))cols = [r[1] for r in c.execute("pragma table_info(session_message)")]total = bad = 0for row in c.execute("select * from session_message"): d = dict(zip(cols, row)) for k, v in list(d.items()): if isinstance(v, str) and v.startswith('{'): try: d.update(json.loads(v)) except Exception: pass content, tok = d.get('content'), d.get('tokens') if not isinstance(content, list) or not isinstance(tok, dict) or not tok.get('reasoning'): continue total += 1 if not any(p.get('type') == 'reasoning' for p in content): bad += 1 print('MISSING reasoning part:', d.get('session_id'), 'tokens.reasoning =', tok['reasoning'], 'parts =', [p.get('type') for p in content])print(f'{bad}/{total} assistant messages with tokens.reasoning > 0 have no reasoning part')PY
Activity
opencode-agent commentedon Oct 12, 2026
Thanks for the detailed report and the database scan. I was able to reproduce this on 2.0.27 with
opencode/big-pickle.I ran a series of one-shot turns (
opencode run -m opencode/big-pickle "Write a short haiku about number N, thinking carefully first."), then scanned the local session database. On a fresh database, 4 of 24 assistant messages withtokens.reasoning > 0had only atextpart. Their reasoning token counts were 1174, 461, 380 and 61. Their text was clean, with no inline chain-of-thought or<think>tags. The other turns had a normalreasoningpart. The script below runs the turns and the scan.What I couldn't establish is where the reasoning gets lost. In the one turn I managed to capture on the wire, Zen streamed
reasoning_contentand OpenCode saved it correctly. I didn't capture an affected turn, so it's still open whether those responses contain reasoning that OpenCode drops or none at all. I also couldn't check the latestdevagainst this model, because Zen's free tier refuses requests from a source build. 2.0.27 is the latest release.Related issues, for reference:
</think>leaks into the text instead of becoming a reasoning partReproduction script (repro.sh)
Run it:
bash repro.sh