Skip to content

[Bug]: Gemma4 tool parser raises RecursionError on arguments nested about 1000 levels deep #20995

Open

Description

@LeizhenZhang

System Info

  • TensorRT-LLM main at 687359e (tensorrt_llm/serve/tool_parser/gemma4_parser.py), pure Python. A CPU is enough to reproduce.
  • Python 3.12
  • Serving path: trtllm-serve <Gemma 4 model> --tool_parser gemma4, chat completions with tools

Who can help?

@NVIDIA/trt-llm-runtime-devs (CODEOWNERS for tensorrt_llm/serve)

Reproduction

from tensorrt_llm.serve.openai_protocol import ChatCompletionToolsParam
from tensorrt_llm.serve.tool_parser.gemma4_parser import Gemma4ToolParser

tools = [ChatCompletionToolsParam(function={"name": "get_weather", "parameters": {"type": "object"}})]
text = "<|tool_call>call:get_weather{opts:" + "{a:" * 1000 + "1" + "}" * 1000 + "}<tool_call|>"
Gemma4ToolParser().detect_and_parse(text, tools)
# RecursionError: maximum recursion depth exceeded

parser = Gemma4ToolParser()
for i in range(0, len(text), 4):
    parser.parse_streaming_increment(text[i:i + 4], tools)
# RecursionError when the call closes

Arrays fail the same way (tags: followed by 1000 [ and 1000 ]).

Expected behavior

The parser returns a result for any model output. Arguments it cannot parse are handled like other malformed arguments, which the parser already logs and skips.

actual behavior

RecursionError leaves detect_and_parse (first parser frame gemma4_parser.py:334) and parse_streaming_increment (first parser frame gemma4_parser.py:476). The non-streaming chat request then fails with HTTP 400 and the generated text is lost. The streaming request ends without its last chunks and without data: [DONE].

additional notes

_parse_gemma4_args calls itself once per nested object (gemma4_parser.py:206), and _parse_gemma4_value and _parse_gemma4_array call each other once per nested array. The handlers at gemma4_parser.py:335 and :478 catch (ValueError, IndexError, TypeError, KeyError). Adding RecursionError there is enough. glm4_parser.py already catches RecursionError for the same reason. I have a fix with a test ready and will open a PR that references this issue.

Activity

  1. added
    Inference runtime<NV>General operational aspects of TRTLLM execution not in other categories.
    on Oct 26, 2026
  2. added 3 commits that reference this issue on Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Inference runtime<NV>General operational aspects of TRTLLM execution not in other categories.

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions