Currently Available: Need a skilled Software Developer for your next project?
Categories
AI Engineering

Why Ollama Prints Tool-Call JSON Instead of Calling the Tool

When you use Ollama to run a local model, the model might print JSON that looks like a function call even though the tool did not run. A tool call is a structured request for the client, the code that communicates with Ollama, to perform an action such as a calculation or information lookup. The model creates the request, Ollama must recognize it in the response, and the client must run the requested function.

Ollama’s chat API puts recognized calls in message.tool_calls. JSON that appears only in message.content is ordinary response text, not a recognized call. Check which field contains the JSON to narrow down the problem: the model might have written text that resembles a call, Ollama might not have recognized it, or the client might not handle structured calls.

A tool call needs three steps

The model cannot run a tool directly. The client sends Ollama a chat request with tool definitions listing the available functions and the arguments each takes. The model can then return a structured request asking the client to run one of those functions.

Ollama’s API documentation shows recognized requests under message.tool_calls, separate from normal text in message.content. After receiving a call, the client must run the named function and send its result back to the model in a follow-up message. The model can then use that result to form its reply.

JSON is a way to represent data. A string such as {"name":"calculator","arguments":...} does not tell the client to run a tool just because it looks like a tool request. Ollama must return the call in the expected structure, and the client needs code that finds the named function and runs it.

Why call-shaped JSON ends up in the text

The request, Ollama, the model, and the client all play a part in tool use. If any of them fails to handle the call, JSON can appear as response text instead.

First, the request must include tool definitions in the format the endpoint expects. A client will not complete the tool cycle if it uses a text-generation endpoint, leaves out the tools parameter, or reads only message.content. The Ollama streaming example handles tool calls separately from ordinary text.

Second, the model’s output format must match what Ollama can recognize. A chat template is the formatting that turns conversation history and tool definitions into the input the model expects. Ollama’s template documentation explains how templates represent messages and tools. If an imported or customized model uses an incompatible template, the model may produce JSON while Ollama fails to identify it as a call. Ollama’s parser can recognize certain model-specific patterns, but arbitrary JSON in a reply is not automatically a tool call.

A setting that restricts the response format can also interfere. Ollama accepts format: "json" or a JSON schema, which tells the model what format to use for its response. In an Ollama issue about JSON format and tools, a user reported that a tool-like object appeared in message.content when JSON formatting was enabled. An Ollama collaborator explained that a response schema can conflict with the structure of a tool call. Test the same request without the format constraint before changing the model or template.

Finally, a model labeled as tool-capable is not guaranteed to make every requested call correctly. In one reported Qwen configuration, different models behaved differently, and a template-related change fixed one case but not another. That report describes specific models and an Ollama version; it does not establish a general failure rate. It does show why capability labels and one successful test are not guarantees for every model variant, prompt, or tool definition.

Find out which step failed

Start with the raw response from Ollama rather than what a chat interface displays. The response field gives you a useful first distinction:

Response What it tells you
message.tool_calls contains the expected function and arguments Ollama returned a structured call. Check whether the client executes it and sends the result back.
message.content contains call-shaped JSON, but message.tool_calls is absent Ollama returned text, not a structured call. Check the request, model format, template, parser behavior, and JSON constraints.
Neither field contains a call Check whether the request included the tools, whether the model chose to use one, and whether the client received the response you expected.

If Ollama returns no structured call, compare the chat request with the documented /api/chat format and check that the tools parameter contains the tool definitions. For a test, remove format: "json" or the response schema. Use one clearly named tool with a simple argument definition, then ask for something that plainly requires it. These checks help you find request and formatting problems before investigating a larger setup.

If the model and request appear compatible, inspect the model’s template, especially when you imported or customized the model. The template determines how Ollama presents tools to the model, while the parser determines whether Ollama recognizes the model’s output as a call. A separate Gemma 4 issue illustrates that parsing and the model’s decision to call are distinct failure points: a parser can leave generated call JSON in content, while a model can also fail to request the tool.

When message.tool_calls contains the call, check what the client does next. The client must find and run the requested function, collect its result, and send that result back to Ollama. Receiving the call object alone does not mean the function ran.

Do not automatically execute JSON found in assistant text as a fallback. Text can contain an example, explanation, or arbitrary data that resembles a command. If you deliberately support text-based calls, validate the function name and argument values, then apply the same authorization checks you use for structured calls.

What I'm building

Delegate tasks. Get software.

Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.

Take a look at vroni.com

Email updates

Usually a new article and a few links I found interesting.

No spam. Unsubscribe with one click.

Leave a Reply

Your email address will not be published. Required fields are marked *