Skip to content

vLLM glm47 parser duplicates tool call arguments in streaming mode causing HTTP 400 #336

Description

@Million-mo

Problem

When using vLLM with the glm47 tool-call parser (used by GLM-4.7/5.0/5.1/5.2 models), streaming tool calls intermittently produce duplicated arguments — two complete JSON objects concatenated together:

{"path": "scratchpad:///fta-workspace/excavator-engine-overheat-workspace"}{"path": "scratchpad:///fta-workspace/excavator-engine-overheat-workspace"}

This causes HTTP 400 errors on the next model request:

Extra data: line 1 column 76 (char 75)

Root Cause

vLLM's glm47 parser (vllm/parser/glm47_moe.py) has a streaming bug where _create_remaining_args_delta() re-emits already-streamed arguments in the final chunk. This is documented in:

The same class of bug exists in SGLang:

Environment

  • Model: GLM-5.2 (deployed as svc/kimi-k2)
  • Backend: vLLM (confirmed by chatcmpl-tool-* tool_call_id format)
  • Proxy: LiteLLM
  • Framework: AgentPool with pydantic-ai
  • Context: >100k tokens, step_index=2

Workaround

PR #335 adds a defensive fix in AgentPool that detects and repairs concatenated JSON in ToolCallPart.args before the message history is sent to the next model request. This prevents the 400 error but does not fix the root cause in vLLM.

Upstream Fix Needed

The root cause is in vLLM's glm47 parser streaming path. The _create_remaining_args_delta() function should not re-emit arguments that have already been streamed. A fix exists only in the vllm-ascend plugin, not in upstream vLLM.

Metadata

Metadata

Assignees

No one assigned

    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