· via dev.to (home feed)
Ollama gemma4 renderer silently drops tool parameters named type or description
Ollama's gemma4 renderer omits tool parameter definitions whose names match JSON Schema keywords, while still listing them as required, so models invent or omit values with no error signal.

What the bug does
According to a write-up on dev.to, Ollama's Go renderer for gemma4 models silently removes a tool parameter's definition whenever the parameter is named type, description, properties, required or nullable. The parameter's name is still written into the rendered required list, so the model is told it must supply a value while being shown nothing about what that value should look like. From the outside, nothing fails: the request returns HTTP 200, the tool call comes back as well-formed JSON with the correct function name, and the log stays quiet.
The observable consequence is that models fill the invisible slot with whatever seems plausible. The author demonstrated this on Ollama 0.33.3 running gemma4:e2b on Debian 13, CPU-only, using a ticket-creation tool (originally from ollama/ollama issue #18468) with two required string parameters, one restricted by an enum to the values urgent_A7 and routine_B3. At temperature 0, two runs per variant:
- Named
kind, the parameter rendered correctly and the model returnedurgent_A7both times. - Named
type, the model returned"type": "urgent"— a word lifted from the user's message and not a legal enum value. - Named
description, the model produced a free-text sentence.
The string urgent_A7 appears nowhere in the prompt except inside the parameter definition, which is why it can only be produced when that definition actually reaches the model. A reporter cited in the write-up, running gemma4:26b, saw a different failure mode: the argument was omitted entirely. Across fourteen attempts, one ticket was created and 35 schema-validation failures were recorded, all on a required parameter called description. The larger model simply refuses to guess where the smaller one improvises; both behaviours stem from the same missing text.
The cause: a lost default argument in a template port
Ollama renders gemma4 prompts in Go, in model/renderers/gemma4.go, and checks the renderer against the model's reference Jinja template stored in model/renderers/testdata/. The Jinja macro format_parameters accepts a filter_keys argument defaulting to false, and it is invoked four times. Three call sites pass nothing, because in those contexts the keys are parameter names. Only one call site — the branch handling an object with no properties map of its own, where the keys genuinely are schema keywords — passes filter_keys=true.
The dev.to author found that the Go port kept the same four call sites and the same skip list, but dropped the argument. writeSchemaProperties filters out keyword-named keys unconditionally, so a filter the template applied in a single case is applied everywhere. Meanwhile, the required list is emitted by a separate function that does no filtering, which is why the parameter name survives there. The model receives contradictory information: one part of the declaration demands a type argument while another never defines it.
A control parameter named typo, which is not on the skip list, renders fine — confirming the problem is the five specific names, not the schema shape. The write-up also notes that the package's existing reference tests pass both before and after the fix, because none of them ever declared a parameter named after a keyword, and that upstream main at commit a43fad18 (2026-09-15) still contains the same code.
Why it is easy to miss
The names involved are natural choices for real schemas: type for a categorical field, description for the free-text field on a ticket, event or product. JSON Schema itself has no rule against property names colliding with keywords — inside properties they occupy a different namespace, and validators handle them correctly. If a tool handler validates against the schema, debugging tends to aim at the model: prompt wording, temperature, whether gemma4 is any good at function calling. If it does not validate, a value like urgent gets stored as a priority code and surfaces later. Ollama also has no debug setting that prints the rendered prompt, so the declaration the model actually receives cannot be observed without reading the renderer or executing it directly.
Fix and workaround
According to the write-up, a twelve-line patch that restores the filter argument resolves the issue: with it applied, the same request returns urgent_A7. Until that lands upstream, the practical workaround is to rename any parameter that collides with the keyword list. Where the name is fixed by an external contract, the author suggests declaring a safe name such as kind to the model and translating it back to type inside the tool handler. The author's toolkit also ships a script, check-tool-param-names.sh, that flags colliding names.
Why it matters
Tool calling is becoming the primary interface for local models, and Ollama is a common way to run them. A renderer bug that corrupts the tool contract without any error signal is worse than a crash: it invites silent data corruption and sends debugging effort in the wrong direction, toward model quality rather than the runtime. It is also a cautionary tale about porting templates between languages — a default argument that did not carry over turned one branch's behaviour into every branch's — and about test suites that never exercise the edge case a bug happens to live in. Anyone running tool-calling agents on Ollama with gemma-class models should audit their parameter names now.
- #ollama
- #function-calling
- #llm
- #local-ai
- #bug