I stumbled on a Gemma 4 chat template bug for tools and fixed it
Posted by EntertainmentBroad43@reddit | LocalLLaMA | View on Reddit | 17 comments
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:
- 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.
- I asked GPT-5.5-high on codex CLI to read the logs and diagnose the issue.
- 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: "".
- It was fixed by a 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.
Meanwhile, you can use this jinja:
https://pastebin.com/p9z3BAC0
Bootes-sphere@reddit
Great catch on that template bug! Your fix probably saves a lot of debugging time for others hitting the same problem. Did you open an issue with the Gemma team, or are you planning to contribute the fix upstream?
BitGreen1270@reddit
Wow is this issue affecting all gemma 4 models? I felt gemma4-26B behaving less optimal than qwen3.6-35-A3B on opencode. Could that be the reason? Should I patch with this and recompile?
JurassicSharkNado@reddit
Nice, I'll have to check this out later. I've been having similar bugs trying to use Gemma for my Goose setup
Healthy_Bedroom5837@reddit
yeah i had to do this a month ago in my app also
onil_gova@reddit
is this why gemma 4 is struggling to make proper tool calls unlike qwen3.6?
https://x.com/i/status/2049156347271528565
EntertainmentBroad43@reddit (OP)
I've given some more thought into this. This is my conclusion thus far.
Gemma 4 supports tool calling, but its Jinja/template protocol is not a faithful JSON schema renderer. It projects tools into a Gemma-specific declaration format, so complex MCP/OpenAI tool schemas can lose semantics or even break template rendering depending on the runtime.
So my fixed jinja will still likely have edge cases if provided tools are peculiar. On one hand I understand Google's reluctance to use JSON for tools (it's token-inefficient and too strict, i think), but it sure makes inference setup difficult.
SourceCodeplz@reddit
Hey thanks for your work! Can you give some references or info on these "Gemma-specific declaration format" ?
EntertainmentBroad43@reddit (OP)
Yeah I’m referring to the official Gemma 4 tool-calling format in Google’s docs. It renders tools as special declarations like <|tool>declaration:... and calls like <|tool_call>call:..., rather than dumping the full JSON schema verbatim.
Ref: https://ai.google.dev/gemma/docs/capabilities/text/function-calling-gemma4
EntertainmentBroad43@reddit (OP)
yeah i saw this post when I was looking for people with similar incidences; if the tools that this person made includes composition, references, unions, or constraints that are not expressed as a direct top-level
type, it could be.SkyFeistyLlama8@reddit
Wait, is this for tool calling using structured outputs or does it affect all tool calling on Gemma 4?
EntertainmentBroad43@reddit (OP)
Not only for structured and affects all gemma 4 models. The original jinja strips out info that are not exposed at the top-level type (at least that’s how i understood it)
EntertainmentBroad43@reddit (OP)
It’s an upstream issue. Likely all gemmas are affected. But it won’t matter for most flat-shaped tool schemas, it is just that my tool did not have a top-level type (i don’ know whether people do this btw. Other models and Claude Haiku called my tool just fine)
yrro@reddit
Is this the PR?
https://huggingface.co/google/gemma-4-31B-it/discussions/91
EntertainmentBroad43@reddit (OP)
Yes. I do python a lil but am not proficient with JSON enough to be sure that this fix’s scope is good. Fixed my tool at least.
yrro@reddit
pull request: https://huggingface.co/google/gemma-4-31B-it/discussions/91
Medium_Chemist_4032@reddit
This is the original gemma4 template, the one with the jinja quirk?
EntertainmentBroad43@reddit (OP)
Oh sorry for the ambiguity. The pastebin link is the fixed jinja template. I fixed the post text to make it clear.