Skip to content

Progress halts with qwen 3.6 35b-a3b with naked tool call in the console #24316

Closed as not planned

Description

@boutell

Description

Not sure why this happens or whether it is properly regarded as a qwen bug, a llama.cpp bug (I'm using a very recent source build), or an opencode bug. But here you are in case it is helpful:

  ┃  Thinking: <tool_call>                                                                                                                                           
  ┃  <function=read>                                                                                                         ▼ Modified Files                        
  ┃  <parameter=filePath>                                                                                                    packages/apostrophe/lib/mongod +22 -1   
  ┃  /Users/ai/apostrophe/packages/apostrophe/modules/@apostrophecms/page/index.js                                           packages/apostrophe/modules/@ap +6 -2   
  ┃  </parameter>                                                                                                            packages/apostrophe/modules/@ap +1993   
  ┃  <parameter=limit>                                                                                                       packages/apostrophe/modules/@ap +5 -1   
  ┃  15                                                                                                                      packages/apostrophe/test/module +1 -4   
  ┃  </parameter>                                                                                                            packages/apostrophe/test/module +1 -1   
  ┃  <parameter=offset>                                                                                                      packages/emulate-mongo-3-driver +1229   
  ┃  2969                                                                                                                    packages/emulate-mongo-3-driver/ +842   
  ┃  </parameter>                                                                                                            sqlite-test.js                    +76   
  ┃  </function>                                                                                                                                                     
  ┃  </tool_call>                                                                                                                                                    
                                                                                                                                                                     
     ▣  Build · Qwen3.6-35B-A3B-UD-IQ4_XS · 22m 13s                                                                     ▄                                            
                                                                                                                                                                     
  ┃                                                                                                                                                                  
  ┃                                                      ~/apostrophe:qwen-opencode              
  ╹▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀▀                                            
                                                                                             94.5K (72%)  ctrl+p commands    • OpenCode 1.14.24                      
                                                                                                                                                                     

I've seen this a number of times: naked XML at the end of the terminal.

Is this qwen producing XML where it should have produced JSON? Is that a thing?

Thanks for all you do!

It's hard to capture this cleanly. Here's a screenshot too:

Image

Plugins

None

OpenCode version

1.14.24

Steps to reproduce

Eventually, in long-running tasks, Qwen3.6-35B-A3B-UD-IQ4_XS running on a very recent llama.cpp build will do it.

Screenshot and/or share link

See above for screenshot

Operating System

MacOS

Terminal

Plain vanilla MacOS Terminal

Activity

  1. added
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on Apr 25, 2026
  2. github-actions commented on Apr 25, 2026

    @github-actions
    Contributor

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

    These issues describe the same behavior: the model outputs raw <tool_call> XML instead of a properly parsed tool invocation, causing the session to stall.

  3. lowlyocean commented on Apr 25, 2026

    @lowlyocean

    I'm seeing this as well as of the recent OpenCode update. Was working fine before with Qwen 3.6 (I haven't changed the model)

  4. boutell commented on Apr 25, 2026

    @boutell
    Author

    #9674 seems related but involves different models and different syntax showing up, so I'll leave this open for now and see what the maintainers think.

  5. lowlyocean commented on Apr 25, 2026

    @lowlyocean

    That's an old issue (Jan.) and only as recently as a few days ago I was running rock solid. So suggests to me it's some recent change rather than something lingering from January.

    v1.14.23 seems to be where the problem started. I'm testing 1.14.22 to see if it's also affected. I know that 1.14.21 worked fine

  6. MRDRMUFN commented on Apr 25, 2026

    @MRDRMUFN

    I've also experienced this issue on v1.14.11 using unsloth/Qwen3.6 27B Q8_K_XL. It cropped up 30K deep with >100K context window.

  7. mingfang commented on Apr 25, 2026

    @mingfang

    this is a problem with the combination of the Qwen models and the reasoning parser.
    There are several issues like these with vLLM vllm-project/vllm#39056

  8. lowlyocean commented on Apr 25, 2026

    @lowlyocean

    Seems this is also related but no clear where to specify "interleaved_reasoning". Is that something to add to llama.cpp args alongside other thinking options, i.e. --chat-template-kwargs "{\"enable_thinking\":true, \"preserve_thinking\":true}" ?

  9. hviden commented on Apr 27, 2026

    @hviden

    我也是同样的问题, llama-cpp+opencode+Qwen3.6-35B-A3B-UD-IQ4_NL.gguf, 并不是必现的, 搞得我很难去测试, 也不知道是怎么引起的, 每次都是中断在tool_call这样的思考中,例如:Thinking: <tool_call>
    <function=edit>
    <parameter=filePath>
    D:\Temp\opencode\vnote\src\store\useAppStore.ts

    <parameter=oldString>
    console.log('migrate Input:', JSON.parse(JSON.stringify(persistedState)).state?.notebooks ? { notebooks: 'present', count: persistedState.state?.notebooks?.length } : 'no notebooks')
    if (!persistedState || typeof persistedState !== 'object') {

    <parameter=newString>


    </tool_call>

    Image
  10. hviden commented on Apr 27, 2026

    @hviden

    我看了ollama的修复方法, ollama/ollama#15022, 看着就是把tool_call放到think外, 我使用的是llama-cpp, 所以我试着同样的方法做了个修复, 我有用官方的chat template file, 直接改一下, 因为我这不是必现, 所以也不知道是否有效, 先试试了

            {%- if '<tool_call>' in reasoning_content %}
                {%- set parts = reasoning_content.split('<tool_call>', 1) %}
                {%- set reasoning_content = parts[0] | trim %}
                {%- set content = '<tool_call>' + parts[1] + (content if content else '') %}
            {%- endif %}
    
  11. removed
    bugSomething isn't working
    coreAnything pertaining to core functionality of the application (opencode server stuff)
    on May 3, 2026
  12. 99sono commented on May 9, 2026

    @99sono

    Same problem here:

    Image

    Instead cline --tui has no problem parsing the output of qwen.
    Here is my docker compose for this:

    version: "3.9"
    
    services:
      qwen3-6-moe-nvfp4:
        image: vllm/vllm-openai:v0.20.1-ubuntu2404
        container_name: qwen3-6-moe-35b-a3b-nvfp4
        hostname: qwen3-6-moe-35b-a3b-nvfp4
        platform: linux/arm64
        ports:
          - "8000:8000"
        volumes:
          - ~/.cache/huggingface:/root/.cache/huggingface
          - /dev/shm:/dev/shm
        shm_size: "32g"
        ipc: host
    
        deploy:
          resources:
            reservations:
              devices:
                - capabilities: [gpu]
    
        environment:
          VLLM_WORKER_MULTIPROC_METHOD: spawn
          PYTORCH_CUDA_ALLOC_CONF: "expandable_segments:True"
          HF_HUB_ENABLE_HF_TRANSFER: "1"
          # Asynchronous CPU/GPU overlap for max speed
          # VLLM_USE_V2_MODEL_RUNNER: "1"
    
        command:
          - "--model"
          - "RedHatAI/Qwen3.6-35B-A3B-NVFP4"
          - "--served-model-name"
          - "Qwen3.6-35B-A3B-NVFP4"
          - "--api-key"
          - "${VLLM_API_KEY:-dummy-key}"
          - "--trust-remote-code"
          - "--host"
          - "0.0.0.0"
          - "--port"
          - "8000"
    
          # --- MEMORY & CONTEXT ---
          # --gpu-memory-utilization: Fraction of GPU VRAM reserved for the model.
          #   0.85 = 85% of 128GB UMA = ~108.8 GB for model weights + KV cache.
          #   Dropped from 0.90 to leave more room for System/CPU in the unified memory architecture.
          #
          # --max-model-len: Maximum context length (prompt + response) in tokens.
          #   262144 = ~256K tokens = maximum context window.
          #   With 128GB UMA, the Spark can handle massive context windows.
          #
          # --max-num-seqs: Maximum number of concurrent request sequences.
          #   Set to 8 for multi-agent / multi-user parallelism.
          - "--gpu-memory-utilization"
          - "0.85"
          - "--max-model-len"
          - "262144"
          - "--max-num-seqs"
          - "8"
    
          # --- BATCHING / PREFILL OPTIMIZATION ---
          # --max-num-batched-tokens controls how many tokens the model can process
          # during the prompt prefill phase (before generating output tokens).
          #
          # Higher values = faster prompt processing but more GPU memory consumed
          # for KV cache allocation. Lower values = slower prefill but more memory
          # available for context window.
          #
          # DGX Spark (Grace Blackwell) trade-offs:
          #   - 65536: Massive prefill for high-speed document ingestion (★ GODZILLA MODE)
          #   - 32768: Fast prefill, still excellent KV cache headroom
          #   -  8192: Conservative prefill, good for smaller contexts
          #
          # 65536 leverages the 128GB unified memory for blazing-fast prefill.
          - "--max-num-batched-tokens"
          - "65536"
    
          # --- ARCHITECTURE & QUANTIZATION ---
          - "--kv-cache-dtype"
          - "fp8_e4m3"
          - "--quantization"
          - "compressed-tensors"
          - "--reasoning-parser"
          - "qwen3"
          - "--tool-call-parser"
          - "qwen3_coder"
          # Auto tool choice is needed for open code, otherwise a snippet of code like the one bellow will raise an error HTTO 400 (bad request).
          #       response = client.chat.completions.create(
          # model="meta-llama/Llama-3.1-8B-Instruct",
          # messages=[{"role": "user", "content": "What's the weather in Paris?"}],
          # tools=tools,
          # tool_choice="auto"
          # )
          # ❌ Raises: 400 "auto" 
          # In short: tool choice requires --enable-auto-tool-choice and --tool-call-parser to be set
          - "--enable-auto-tool-choice"
    
          # --- KERNEL FUSION (The Speed Unlock) ---
          - "--moe-backend"
          - "flashinfer_cutlass"
          - "--enable-prefix-caching"
          - "--enable-chunked-prefill"
    
          # --- STARTUP OPTIMIZATIONS (Boot Faster) ---
          # Force disk I/O overlap
          - "--safetensors-load-strategy"
          - "prefetch"
          
          # Stop capturing useless batch graphs you won't use in single-user mode
          - "--max-cudagraph-capture-size"
          - "1"
    
          # --- SPECULATIVE DECODING (Speed Enhancement) ---
          # N-Gram Speculative Decoding: Uses existing KV cache to guess
          # repeating tokens. Zero memory overhead. Can push generation from
          # ~112 tokens/s → 150-200+ tokens/s if acceptance rate > 50%.
          # - "--speculative-model"
          # - "[ngram]"
          # - "--num-speculative-tokens"
          # - "5"
          # error: vllm: error: unrecognized arguments: --speculative-model [ngram] --num-speculative-tokens 5
          # something is wrong there. 
    
          # --- MTP ALTERNATIVE (Commented Out) ---
          # Qwen3.6 native Multi-Token Prediction — enabled for reference.
          # To use, uncomment below and comment out the ngram flags above.
          # Requires vLLM 0.20.0+ with MTP support.
          #
          - "--speculative-config"
          - '{"method":"qwen3_next_mtp","num_speculative_tokens":2}'
    
        networks:
          - development-network
    
    networks:
      development-network:
        external: true
  13. 99sono commented on May 10, 2026

    @99sono

    Right now, with open code 1.14.46, for whatever reason, things seem to be working normally.

  14. RevengeRip commented on May 10, 2026

    @RevengeRip

    Right now, with open code 1.14.46, for whatever reason, things seem to be working normally.

    Still halts for me

    Image
  15. sghaskell commented on May 13, 2026

    @sghaskell

    +1

    I'm getting tool call leaks multiple times a session.

    Qwen3.6-27B running in vLLM

    v1.14.48

    Image
  16. soern commented on May 14, 2026

    @soern

    +1 on v1.14.50, using Qwen3.6-35B-A3B
    This also happened to me on other Qwen 3.5 model.

    Image
  17. sghaskell commented on May 17, 2026

    @sghaskell

    PR opened to address this issue: #27984

  18. sghaskell commented on May 17, 2026

    @sghaskell

    You can test this fix locally:

    # Clone fork and checkout the fix branch
    git clone --branch fix/strip-dangling-xml-tags https://github.com/sghaskell/opencode.git
    cd opencode
    
    # Install dependencies
    bun install
    
    # Build
    bun run build
    
    # Run with your vLLM/Qwen3 config
    OPENCODE_BASE_URL=http://localhost:8000/v1 opencode

    The fix strips trailing XML artifacts (backtick-lt/parameter-gt, backtick-lt/function-gt, ␐) from streaming text deltas before they reach the TUI. Test with a multi-tool-call prompt to verify no XML leakage.

  19. danielcherubini commented on May 28, 2026

    @danielcherubini

    Fix worked

  20. fenrir-labs76 commented on Jun 29, 2026

    @fenrir-labs76

    Reproduced on qwen3.6-35b (128K context) via Ollama with a different symptom: silent infinite spinner.

    Tracing the streaming protocol reveals what's actually happening. Ollama's OpenAI-compatible endpoint puts thinking tokens in delta.reasoning, not delta.content:

    data: {"choices":[{"delta":{"role":"assistant","content":"","reasoning":"Here's a thinking process:\n\n1.  **Analyze..."}}]}
    data: {"choices":[{"delta":{"content":"","reasoning":"'s"}}]}

    (thousands of chunks, all content: "", reasoning: "...")

    @ai-sdk/openai-compatible reads delta.content only — delta.reasoning is silently dropped. Every chunk arrives with content: "". From opencode's perspective the model is streaming but producing nothing — spinner shows "working", zero text is ever rendered, and the user sees an infinite silent spinner.

    This also explains the naked-XML-in-thinking symptom in the original report: if the model emits a tool call inside its thinking chain, it lands in delta.reasoning and opencode never processes it as a tool call. Progress halts because the tool never executes.


    Reproduced with:

    • qwen3.6-35b via Ollama's /v1 endpoint
    • @ai-sdk/openai-compatible, opencode 1.17.11
    curl http://localhost:11434/v1/chat/completions \
      -d '{"model":"qwen3.6-35b","messages":[{"role":"user","content":"say hi"}],
           "stream":false,"max_tokens":5000}'
    # → content: "Hi there, how are you?"  (22 chars)
    # → reasoning: (9539 chars of thinking)
    # → finish_reason: stop

    The model responds correctly — the content is there. It's just in the wrong field. @ai-sdk/openai-compatible never surfaces delta.reasoning to opencode, so the response appears empty even though the model completed successfully.


    Suggested fix: when @ai-sdk/openai-compatible receives delta.reasoning chunks, surface them as a "thinking" stream part (or at minimum update the spinner label to "Thinking…"). The UI infrastructure already exists — the "Thinking:" prefix is visible in the original report's screenshot. It just isn't wired to the delta.reasoning path from Ollama.

  21. brusacco commented on Jul 24, 2026

    @brusacco

    Happened to me just now, current OpenCode version and QWEN 3.6 35b as well (ollama)

    <|mask_start|>Now I need to create the specs and design artifacts. Let me write them both.<|mask_end|>

  22. Gr33n93 commented on Jul 31, 2026

    @Gr33n93

    Reproduced again on 2026-07-31 with OpenCode 1.18.10.

    Environment:

    • Fedora Linux
    • OpenCode 1.18.10
    • @ai-sdk/openai-compatible
    • local llama.cpp OpenAI-compatible endpoint (no Ollama or LM Studio)
    • ThinkingCap Qwen 3.6 27B Q6_K MTP Vision
    • configured context: 200k; failing assistant message had 34,254 input tokens

    Observed in OpenCode's SQLite session data, the assistant reasoning ended with:

    I'll work with the cube's vertices in edit mode to sculpt the shape.
    </parameter>
    </function>
    </tool_call>
    

    That message was stored with finish: "stop" and no tool part was created, so the TUI stopped progressing.

    After I sent a single ?, the next assistant turn emitted a properly structured blender_execute_blender_code tool call and it completed successfully. The model endpoint and tool were therefore still healthy; only that tool-call turn was lost.

    A local history-sanitizer plugin is enabled, but it only removes historical Qwen reasoning before replay. It does not modify the current streamed response or tool call.

    This looks like the exact naked-XML failure described here, and it still occurs on 1.18.10. It also happened relatively early (~34k input tokens), not only near the end of a 100k+ context. PR #27984 is still open, so its proposed mitigation does not appear to be present in the released version.

  23. nemoobc commented on Aug 28, 2026

    @nemoobc

    Adding a +1 / confirmation for this — same symptom on a recent release.

    Environment:

    • opencode binary 1.18.23 (latest), [email protected]
    • node v24.18.0
    • Linux (Termux/Android, arm64), default setup, no plugin

    Symptom: Intermittently, raw tool-call tags (<parameter name="...">...</parameter>, stray <parameter>, </parameter>) appear as literal text in the TUI above the assistant message. Tools still execute fine — it's a rendering/parsing artifact. Most likely to happen on multi-step turns (bash + edit/glob back-to-back).

    Re: PR #27984: Confirming what @Gr33n93 reported on 1.18.10 — the proposed fix is still open and not present in 1.18.23, so this is still reproducible on the latest release.

    Happy to add a screenshot on next occurrence. Thanks for tracking this — would love to see #27984 (or the #30633 approach) merged.

  24. thdxr commented on Oct 11, 2026

    @thdxr
    Member

    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 𝕺𝖕𝖊𝖓𝕮𝖔𝖉𝖊

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