vllm - ✅(Solved) Fix [Bug]: Qwen3Coder tool parser crashes on malformed <parameter=...> (ValueError: substring not found) [1 pull requests, 1 participants]

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…
GitHub stats
vllm-project/vllm#39771Fetched 2026-04-16 06:36:43
View on GitHub
Comments
0
Participants
1
Timeline
1
Reactions
0
Author
Participants
Timeline (top)
cross-referenced ×1

Error Message

ERROR [qwen3coder_tool_parser.py:344] Error in extracting tool call from response. ERROR [qwen3coder_tool_parser.py:344] Traceback (most recent call last): ERROR [qwen3coder_tool_parser.py:344] File ".../qwen3coder_tool_parser.py", line 317, in extract_tool_calls ERROR [qwen3coder_tool_parser.py:344] self._parse_xml_function_call(function_call_str, request.tools) ERROR [qwen3coder_tool_parser.py:344] File ".../qwen3coder_tool_parser.py", line 259, in _parse_xml_function_call ERROR [qwen3coder_tool_parser.py:344] idx = match_text.index(">") ERROR [qwen3coder_tool_parser.py:344] ^^^^^^^^^^^^^^^^^^^^^ ERROR [qwen3coder_tool_parser.py:344] ValueError: substring not found

Fix Action

Fix

Use str.find(">") and skip on -1, matching the existing safe pattern used for the function name. PR follows.

PR fix notes

PR #39772: [Bugfix] Skip malformed parameters in qwen3coder tool parser

Description (problem / solution / changelog)

Summary

  • Replace str.index(">") with str.find(">") in Qwen3CoderToolParser._parse_xml_function_call and skip parameters that lack the name>value separator
  • Match the safe-handling pattern already used for the function name a few lines above
  • Add a regression test

Fixes #39771

Motivation

When the model emits a malformed <parameter=...> (truncation, dropped >, etc.), match_text.index(">") raises ValueError: substring not found. The error is swallowed by the broad except Exception in extract_tool_calls, but the catch discards the entire response's tool calls — including any well-formed parameters / other tool calls in the same output — and falls back to plain text content. Skipping the malformed parameter individually preserves the rest of the response.

The function name path on the preceding lines already does exactly this:

end_index = function_call_str.find(">")
if end_index == -1:
    return None

The parameter loop should be consistent.

Test plan

  • New regression test test_malformed_parameter_no_gt_delimiter verifies that a malformed parameter is skipped while a well-formed one in the same call is parsed correctly
  • Existing parser tests (tests/tool_parsers/test_qwen3coder_tool_parser.py) still pass — including the previous related regression test_malformed_xml_no_gt_delimiter

Changed files

  • tests/tool_parsers/test_qwen3coder_tool_parser.py (modified, +24/-0)
  • vllm/tool_parsers/qwen3coder_tool_parser.py (modified, +12/-1)

Code Example

ERROR [qwen3coder_tool_parser.py:344] Error in extracting tool call from response.
ERROR [qwen3coder_tool_parser.py:344] Traceback (most recent call last):
ERROR [qwen3coder_tool_parser.py:344]   File ".../qwen3coder_tool_parser.py", line 317, in extract_tool_calls
ERROR [qwen3coder_tool_parser.py:344]     self._parse_xml_function_call(function_call_str, request.tools)
ERROR [qwen3coder_tool_parser.py:344]   File ".../qwen3coder_tool_parser.py", line 259, in _parse_xml_function_call
ERROR [qwen3coder_tool_parser.py:344]     idx = match_text.index(">")
ERROR [qwen3coder_tool_parser.py:344]           ^^^^^^^^^^^^^^^^^^^^^
ERROR [qwen3coder_tool_parser.py:344] ValueError: substring not found

---

end_index = function_call_str.find(">")
if end_index == -1:
    return None

---

<tool_call>
<function=get_current_weather>
<parameter=truncated_param_no_gt<parameter=city>Dallas</parameter>
</function>
</tool_call>
RAW_BUFFERClick to expand / collapse

Your current environment

vLLM main branch with Qwen/Qwen3-Coder-30B-A3B-Instruct-FP8 (or any Qwen3-Coder model).

🐛 Describe the bug

Qwen3CoderToolParser._parse_xml_function_call uses str.index(">") on each <parameter=...> match. When a parameter is truncated or malformed (no > separator between name and value), this raises ValueError: substring not found.

The error is caught by a broad except Exception in extract_tool_calls, but the catch causes the entire tool call extraction to fail — discarding any well-formed parameters and other tool calls in the same response, and forcing a fallback to plain text content.

Stack trace

ERROR [qwen3coder_tool_parser.py:344] Error in extracting tool call from response.
ERROR [qwen3coder_tool_parser.py:344] Traceback (most recent call last):
ERROR [qwen3coder_tool_parser.py:344]   File ".../qwen3coder_tool_parser.py", line 317, in extract_tool_calls
ERROR [qwen3coder_tool_parser.py:344]     self._parse_xml_function_call(function_call_str, request.tools)
ERROR [qwen3coder_tool_parser.py:344]   File ".../qwen3coder_tool_parser.py", line 259, in _parse_xml_function_call
ERROR [qwen3coder_tool_parser.py:344]     idx = match_text.index(">")
ERROR [qwen3coder_tool_parser.py:344]           ^^^^^^^^^^^^^^^^^^^^^
ERROR [qwen3coder_tool_parser.py:344] ValueError: substring not found

Inconsistency in the same function

The function name path on the preceding lines already uses the safe pattern:

end_index = function_call_str.find(">")
if end_index == -1:
    return None

but the parameter loop uses the unsafe .index(">").

Reproduction

A model output like:

<tool_call>
<function=get_current_weather>
<parameter=truncated_param_no_gt<parameter=city>Dallas</parameter>
</function>
</tool_call>

crashes the parser and discards the well-formed city=Dallas parameter.

Expected behavior

Malformed <parameter=...> matches without a > separator should be skipped (with a warning), and other valid parameters / tool calls in the same response should still be parsed.

Fix

Use str.find(">") and skip on -1, matching the existing safe pattern used for the function name. PR follows.

extent analysis

TL;DR

Replace str.index(">") with str.find(">") in Qwen3CoderToolParser._parse_xml_function_call to safely handle malformed parameters.

Guidance

  • Identify the line of code using str.index(">") in Qwen3CoderToolParser._parse_xml_function_call and replace it with str.find(">").
  • Add a conditional check to skip parsing when str.find(">") returns -1, indicating a malformed parameter.
  • Verify the fix by testing with a model output containing a truncated parameter, ensuring that well-formed parameters are still parsed.
  • Review the existing safe pattern used for the function name path to ensure consistency in handling malformed inputs.

Example

idx = match_text.find(">")
if idx == -1:
    # Skip parsing and log a warning for the malformed parameter
    print("Warning: Malformed parameter encountered. Skipping...")
    continue

Notes

This fix assumes that the str.find(">") method is sufficient for handling malformed parameters. Additional error handling or input validation may be necessary depending on the specific requirements of the Qwen3CoderToolParser.

Recommendation

Apply the workaround by replacing str.index(">") with str.find(">") and adding a conditional check to skip malformed parameters, as this will allow the parser to handle truncated parameters without discarding well-formed data.

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…

FAQ

Expected behavior

Malformed <parameter=...> matches without a > separator should be skipped (with a warning), and other valid parameters / tool calls in the same response should still be parsed.

Still need to ship something?

×6

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

Back to top recommendations

TRENDING

vllm - ✅(Solved) Fix [Bug]: Qwen3Coder tool parser crashes on malformed <parameter=...> (ValueError: substring not found) [1 pull requests, 1 participants]