I stumbled on a Gemma 4 chat template bug for tools and fixed it

Reddit r/LocalLLaMA / 4/29/2026

💬 OpinionDeveloper Stack & InfrastructureSignals & Early TrendsTools & Practical Usage

Key Points

  • The author found that Gemma 4’s default chat template mishandles tool parameters defined with JSON Schema patterns like `anyOf: [$ref, null]`, causing the schema’s type information to be lost before the model sees it.
  • This bug appears when the JSON Schema does not have a direct top-level `type`, with the useful structure instead living inside `anyOf`, `$ref`, and `$defs`.
  • After diagnosing logs across Qwen 3.5 and Gemma 4, the author fixed the issue by making small changes to Gemma’s chat template Jinja so tool schemas are rendered correctly.
  • The author submitted a PR to Hugging Face for `google/gemma-4-31B-it`, later expanding the Jinja to preserve more JSON Schema constructs such as `$ref`, `anyOf/oneOf/allOf`, `$defs`, `enum/const`, nullable types, and array/object item/property structures.

TLDR: tool parameters using the common JSON Schema pattern `anyOf: [$ref, null]` are rendered into the prompt as empty `type` fields. This strips the useful schema information before the model sees it.

--

Long, rambling version:

Gemma 4 was having issues with calling my custom MCP tool on >3 inference engines, while Qwen3.5 and gpt-oss-20b were doing fine.

I guessed it was either a chat template issue or inference library issue on an edge case, and thought time would sort it out, since many people were happy with Gemma 4 as an agent.

It didn't for at least 2 weeks now and I had no choice but to investigate myself.

What I did:

  1. I made a verbose log file via llama-server, running the same prompt/tool on Qwen3.5-27B-Q4_K_M and gemma-4-31B-it-Q4_K_S on a macbook pro.
  2. I asked GPT-5.5-high on codex CLI to read the logs and diagnose the issue.
  3. Found it in couple of minutes; the default Gemma chat template assumes tool parameters have a direct type field. Which means it will not work with JSON schema shapes like nullable refs:

{"anyOf": [{"$ref": "#/$defs/SomeObject"}, {"type": "null"}]}

where there is no top-level type. The useful structure is inside anyOf and $defs. The template drops anyOf, $ref, and $defs, then renders it as type: "".

  1. It was fixed by small changes in the chat template jinja, and now Gemma is calling my tool perfectly!

Anyway I made a PR on HF, google/gemma-4-31B-it.

<UPDATE>

I realized that I just addressed one of many issues arising JSON Schema shapes that do not expose their meaning through a direct top-level type. I updated the jinja to address:

now the jinja preserves:

- $ref

- anyOf

- oneOf

- allOf

- $defs

- enum

- const

- type: ["string", "null"]

- items / properties for type arrays containing array or object

- null values as null

The fixed jinja:
https://pastebin.com/tBAHN6FV

submitted by /u/EntertainmentBroad43
[link] [comments]