Bug: reasoning_content is replayed in the request history, causing tool-call markup leakage
Maintainers usually reply within 1 day
Nobody has claimed this yet.
Assessment
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Newbie friendliness
- 66/100
- Issue type
- Bug
- Clarity
- Clearly specified
- Activity status
- Active
- Tech stack
- typescript
Research direction
Start by tracing how session history is assembled into provider request payloads, then find where assistant messages retain reasoning_content. Check whether that field is sent in subsequent requests and whether the request-building path has tests for reasoning models. Done means history can still retain reasoning for display while requests omit it, with a regression test covering the behavior.
Written by the indexing model from the issue text.
Description
opencode persists the model's reasoning_content (chain-of-thought) in the session history and sends it back in every subsequent request. DeepSeek's API states that reasoning_content is the current turn's CoT and must not be passed back.
Impact: with reasoning models (e.g. deepseek-v4.1-flash), the model imitates patterns from its own past reasoning - including malformed tool-call markup - so tool calls are silently lost (tool_calls == 0, finish_reason == "stop"). It is self-reinforcing: the more it leaks, the more that markup appears in reasoning.
A/B (one captured opencode request, 1011 messages / 4.78 MB, replayed to the same endpoint with a "write a ~120-line script" instruction appended):
| variant | leak rate |
|---|---|
with reasoning_content |
4 / 5 |
without reasoning_content |
0 / 5 |
| last 300 msgs, with | 2 / 5 |
| last 300 msgs, without | 0 / 5 |
"Leak" is defined strictly as: markup inside delta.content and tool_calls == 0 and finish_reason == "stop".
Observed message structure in the captured request: assistant messages 480, of which reasoning_content present in 480.
Excluded by A/B: max_tokens (256k vs 128k -> 4/5 vs 4/5), system prompt content, temperature, tool_choice, parallel_tool_calls, thinking/reasoning_effort fields, and endpoint (official api.deepseek.com vs the opencode gateway). The dose-response (100 msgs 0/5 -> 300 msgs 2-3/5 -> 1009 msgs 4/5) is fully explained by the replayed CoT.
A different client (CodeBuddy) with the same model and the same real leaked-text corpus in a 1.13 MB history does not reproduce it (0/5).
Suggested fix: do not send reasoning_content back when building the request payload (keep it for UI display only); optionally gate behind a provider/model capability flag.
Reproduction: run a long session with a reasoning model, then ask it to write a long file - occasionally the tool call is emitted as text; re-sending the same request with reasoning_content stripped removes the failure (0/5 vs 4/5).
Environment: opencode 2.0.30 (Windows), providers opencode-go and official deepseek, model deepseek-v4.1-flash (variant max).
- Dominant language
- TypeScript
- Stars
- 215k
- Forks
- 28.9k
- Avg merge
- 11h 19m
- Merged PRs (30d)
- 320
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from anomalyco/opencode
-
pending close triaging
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
anomalyco/opencode#57209 · 1 comment ·
Maintainers usually reply within 1 day
-
reproduced
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
anomalyco/opencode#57127 · 2 comments ·
Maintainers usually reply within 1 day
-
pending close triaging
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
anomalyco/opencode#57070 · 1 comment ·
Maintainers usually reply within 1 day
-
Plan mode leave reminder becomes the final user turn after a tool-driven agent switch, models refusePossibly taken @Veld101 claimed this 1 day ago. Openreproduced
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
anomalyco/opencode#57013 · 1 comment ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 64/100
anomalyco/opencode#56891 · 2 comments ·
Maintainers usually reply within 1 day
All issues in anomalyco/opencode
Similar issues
-
Sequências em espanhol: «Atualizado em», a aba «Fila» e o valor 'pause' ainda saem em portuguêsOpen
Difficulty 2/5 1-3 hours Newbie friendliness 77/100
melgarafael/DeskcommCRM#3104 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
Maintainers usually reply within 1 day
-
bug service: webapp
Difficulty 2/5 1-3 hours Newbie friendliness 82/100
Ocelot-Social-Community/Ocelot-Social#10684 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
nicobailon/pi-subagents#2978 ·
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 66/100
getsentry/sentry-conventions#732 · 1 comment ·
Maintainers usually reply within 1 day