Skip to content

Zen gateway (opencode-go): deepseek-v4.1-flash degenerates into infinite pre-tool-call repetition loops; same model via direct DeepSeek API is clean #51839

Closed as not planned

Description

@vlat456

Summary

The same model (deepseek-v4.1-flash) behaves differently depending on the provider route: via opencode-go (Zen gateway, https://opencode.ai/zen/go/v1) it falls into infinite autoregressive repetition loops before tool calls; via the direct DeepSeek API (deepseek/deepseek-flash) the exact same sessions run clean. We have a clean A/B (same weights, two serving stacks, stable difference across many runs), session transcripts of the loops, and a plausible root cause.

This looks like the gateway mishandling reasoning models' tool-calling transitions (most likely: feeding reasoning_content back into the conversation, and/or missing sampling safeguards).

Environment

  • opencode: v1.18.3x (2026-09-27), macOS (darwin/arm64)
  • Provider A (degenerates): opencode-go — https://opencode.ai/zen/go/v1, model deepseek-v4.1-flash, requests carry x-opencode-session header
  • Provider B (clean): deepseek — https://api.deepseek.com/v1, model deepseek-flash
  • Agent harness: custom subagents with tools (bash/read/edit), temperature 0.2–0.3, up to 100+ tool-call steps per session

Evidence

1. Clean A/B on the same model

  • Same session content replayed against both providers:
    • opencode-go/deepseek-v4.1-flash → enters repetition attractor loops, repeatedly
    • deepseek/deepseek-flash (direct) → runs to completion, repeatedly
  • The user's manual switch mid-session (gateway → direct) made the 400/loop problems disappear immediately; switching back reproduces them.

2. Loop transcripts (verbatim, from agent=coding and primary orchestrator sessions)

Pattern A — English (the model stalls before emitting a tool call, then loops):

Let me run.
Let me execute.
Let me do it now.
OK.
Let me run.
Let me execute.
…(repeats for 100+ lines)

Pattern B — same class, different vocabulary:

Emit.
OK.
Now.
OK.
Emitting.
OK.
I must emit. Doing it.
Let me grep.
Emit.
OK — emitting.
Recon.
OK.
…(fixed ~12-line cycle, repeats indefinitely)

Russian-localized session, same fixed cycle:

Сгенерируй.
OK — генерирую.
Вызов.
OK.
Сейчас.
OK.
Генерация.
OK.
Я должен выполнить вызов. Занимаюсь этим.
…(repeats)

Notably, the vocabulary of the loops mirrors instruction text from the agent prompts (compliance-narration words like "emit"/"OK"/"call") — consistent with the model regurgitating its own prior assistant text, i.e. the loop is self-feeding through conversation history.

3. What the direct API does differently

  • Direct DeepSeek API responses carry reasoning in reasoning_content, and the model was trained with the contract that reasoning_content must not be fed back as input on subsequent turns.
  • Hypothesis: the Zen gateway re-includes the assistant's reasoning/hesitation text in subsequent messages (or otherwise alters the reasoning→tool_call transition), so the model keeps seeing — and then predicting — its own deliberation text instead of transitioning to the tool-call token.
  • Secondary suspect: the gateway passes through low temperature (0.2–0.3) without vendor-side anti-repetition safeguards; greedy-ish decoding makes the attractor inescapable once seeded.

4. Related gateway-side quirks observed the same day

  • stream error … AI_APICallError: Bad Request on gateway requests whose message history the direct API accepts; the gateway's error body is truncated to {"model":"deepseek-v4.1-flash"} — no diagnostics are recoverable.
  • After such an error, opencode disposes and recreates the whole instance (feels like a hang).

Expected vs actual

  • Expected: the same model behind the Zen gateway behaves like the direct API — reasoning handled per the provider contract (reasoning_content not fed back), tool calls emitted after deliberation, sampling sane for low-temperature agent workloads.
  • Actual: gateway route reliably degenerates into infinite pre-tool-call narration loops on agentic workloads; direct route is stable.

Reproduction sketch

  1. Configure two providers: opencode-go (Zen, x-opencode-session header) and direct DeepSeek, same model tier (deepseek-v4.1-flash / deepseek-flash).
  2. Run an agentic session with ~50+ tool-call steps and a prompt that requires multi-step verification (e.g., "run these tests, then narrow failing ones, then re-run").
  3. Gateway route: assistant text degenerates into fixed repetition cycles ("Let me run. / Let me execute. / …" or localized equivalents) instead of emitting the tool call.
  4. Direct route: same session completes.

Happy to provide full session JSONL dumps (DB rows with message/part payloads) for both routes if that helps debugging.

Activity

  1. github-actions commented on Sep 28, 2026

    @github-actions
    Contributor

    This issue doesn't fully meet our contributing guidelines.

    What needs to be fixed:

    • Please use the Bug Report template and include the report in its required Description field. The current custom Summary/Evidence layout does not include that required field.
    • Please shorten the description substantially. It is an unusually long, highly structured write-up with extensive transcript examples and speculative root-cause details; keep the concise symptom, essential environment information, and reproduction steps.

    Please edit this issue to address the above within 2 hours, or it will be automatically closed.


    This issue might be a duplicate of existing issues. Please check:

    • #50634: OpenCode Go with DeepSeek V4.1 Flash also produces repetitive narration instead of tool calls.

    If you believe this was flagged incorrectly, please let a maintainer know.

  2. github-actions commented on Sep 28, 2026

    @github-actions
    Contributor

    This issue has been automatically closed because it was not updated to meet our contributing guidelines within the 2-hour window.

    Feel free to open a new issue that follows our issue templates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions