ollama - 💡(How to fix) Fix qwen3.6 occasionally violates its own tool-call template; qwen3.5 parser returns 500 instead of tolerating the drift [1 pull requests]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…

Error Message

A small single-shot curl with a tools[] field does not reliably fail (tested 20× — 20/20 200 OK). Failures cluster on longer multi-iteration turns with substantial conversation history. Bypassing the parser as shown above is the cleanest reproduction of the underlying model behavior; the parser error is then a consequence of that behavior reaching the unmarshal path.

  • model/parsers/qwen3coder.go:64parseToolCall returning the unmarshal error
  • model/parsers/qwen35.go:96 — wrapper logging the same error time=2026-05-31T21:24:28.906Z level=WARN source=qwen3coder.go:64 msg="qwen tool call parsing failed" error="expected element type <function> but have <parameter>" time=2026-05-31T21:24:28.906Z level=WARN source=qwen35.go:96 msg="qwen3.5 tool call parsing failed" error="expected element type <function> but have <parameter>"

Root Cause

Root cause appears to be model drift, not a wrong parser

Fix Action

Fixed

Code Example

curl http://localhost:11434/api/chat -d '{
  "model": "qwen3.6:27b",
  "stream": false,
  "think": false,
  "messages": [
    {"role":"system","content":"You are a helpful assistant. When you need to call a function, emit it in XML form with <function=name> wrapping <parameter=key>value</parameter> elements. Always make the call."},
    {"role":"user","content":"What is the weather in Paris? Use the function get_weather(location: string)."}
  ]
}'

---

<function=get_weather>
<parameter=location>Paris</parameter>
</function>
</function>
</function_invocation>

---

RENDERER qwen3.5
PARSER   qwen3.5

---

time=2026-05-31T21:24:28.906Z level=WARN source=qwen3coder.go:64 msg="qwen tool call parsing failed" error="expected element type <function> but have <parameter>"
time=2026-05-31T21:24:28.906Z level=WARN source=qwen35.go:96 msg="qwen3.5 tool call parsing failed" error="expected element type <function> but have <parameter>"
[GIN] 2026/05/31 - 21:24:28 | 500 |   4.07683667s | POST     "/api/chat"
RAW_BUFFERClick to expand / collapse

What is the issue?

qwen3.6:27b (and the other qwen3.6 tags) registers PARSER qwen3.5 / RENDERER qwen3.5. With tools[] populated on a chat completion, the qwen3.5 parser intermittently fails to unmarshal qwen3.6's tool-call output and Ollama returns 500. The bug is intermittent: simple curl tests usually succeed, but cumulatively painful for any agent that issues many tool-using calls in a session.

Root cause appears to be model drift, not a wrong parser

Qwen's official tokenizer_config.json for Qwen/Qwen3.6-27B specifies the same <tool_call><function=…><parameter=…>…</parameter></function></tool_call> format Ollama's qwen3.5 renderer expects, with this <IMPORTANT> reminder in the template:

"Function calls MUST follow the specified format: an inner <function=...></function> block must be nested within <tool_call></tool_call> XML tags"

So the renderer/parser pair is structurally correct against Qwen's stated spec. The bug is that qwen3.6 doesn't reliably follow its own template — it intermittently drifts to what looks like an older <function_invocation>…</function_invocation> wrapper. Evidence below.

Evidence — model emits malformed XML

Bypassing the parser (no tools[] field), asking qwen3.6:27b to emit a tool call as XML:

curl http://localhost:11434/api/chat -d '{
  "model": "qwen3.6:27b",
  "stream": false,
  "think": false,
  "messages": [
    {"role":"system","content":"You are a helpful assistant. When you need to call a function, emit it in XML form with <function=name> wrapping <parameter=key>value</parameter> elements. Always make the call."},
    {"role":"user","content":"What is the weather in Paris? Use the function get_weather(location: string)."}
  ]
}'

message.content returned (107 chars verbatim):

<function=get_weather>
<parameter=location>Paris</parameter>
</function>
</function>
</function_invocation>

Two issues:

  1. Spurious extra </function> close tag.
  2. </function_invocation> close tag with no matching open — looks like a leak from an older training format.

When the same model is invoked with tools[] populated, the qwen3.5 renderer wraps the conversation with <tool_call> instructions and qwen3.6 mostly complies. But when the drift occurs inside a <tool_call> block, parseToolCallxml.Unmarshal rejects the input because the first child element is <parameter> (or stray garbage) rather than <function>.

Reproducing the 500 directly

A small single-shot curl with a tools[] field does not reliably fail (tested 20× — 20/20 200 OK). Failures cluster on longer multi-iteration turns with substantial conversation history. Bypassing the parser as shown above is the cleanest reproduction of the underlying model behavior; the parser error is then a consequence of that behavior reaching the unmarshal path.

ollama show qwen3.6:27b returns:

RENDERER qwen3.5
PARSER   qwen3.5

Suggested fix (Ollama side — defense-in-depth)

Tighten the existing qwen3.5 parser (model/parsers/qwen3coder.go) to tolerate this specific drift: inside a <tool_call> block, anchor on the first <function=…> opening tag and skip any stray closing tags / unmatched wrappers (</function>, </function_invocation>) before handing to xml.Unmarshal. Localized change, avoids any model-manifest churn, and the failure mode is well-characterized by the captured output above.

A complementary upstream fix at the Qwen team would address the root cause, but as a downstream consumer the parser-tolerance change unblocks users today.

Happy to PR the parser-tolerance change if there's interest — let me know.

Related code paths (main)

  • model/parsers/qwen3coder.go:64parseToolCall returning the unmarshal error
  • model/parsers/qwen35.go:96 — wrapper logging the same error
  • model/renderers/qwen35.go:1-36 — the prompt format the model is told to use

Relevant log output

time=2026-05-31T21:24:28.906Z level=WARN source=qwen3coder.go:64 msg="qwen tool call parsing failed" error="expected element type <function> but have <parameter>"
time=2026-05-31T21:24:28.906Z level=WARN source=qwen35.go:96 msg="qwen3.5 tool call parsing failed" error="expected element type <function> but have <parameter>"
[GIN] 2026/05/31 - 21:24:28 | 500 |   4.07683667s | POST     "/api/chat"

OS

Linux

GPU

Nvidia

CPU

Intel

Ollama version

0.24.0

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING