[GH-ISSUE #13519] llama3.2:3b outputs tool calls as JSON in content instead of using tool_calls field #55420

Closed
opened 2026-04-29 09:09:21 -05:00 by GiteaMirror · 4 comments
Owner

Originally created by @sacenox on GitHub (Dec 18, 2025).
Original GitHub issue: https://github.com/ollama/ollama/issues/13519

What is the issue?

llama3.2:3b outputs tool calls as JSON in content instead of using tool_calls field

Description

When using llama3.2:3b with the Ollama npm library and including tools in the request, the model outputs tool calls as JSON text in the content field instead of using the tool_calls field like other models do.

Expected Behavior

The model should return tool calls in the tool_calls field of the response, similar to how other models (e.g., gpt-oss:latest) handle tool calling.

Actual Behavior

The model outputs tool calls as JSON text in the content field, wrapped in code blocks:

{"name": "query_web_search", "parameters": {"query": "install ollama models"}}

The tool_calls field is empty or not present in the response chunks.

Steps to Reproduce

  1. Use Ollama npm library version 0.6.3
  2. Send a chat request to llama3.2:3b model with tools included
  3. Observe the response - tool calls appear as JSON in content instead of tool_calls

Example code:

import ollama from "ollama";

const tools = [
  {
    type: "function",
    function: {
      name: "query_web_search",
      description: "Perform a web search",
      parameters: {
        type: "object",
        properties: {
          query: {
            type: "string",
            description: "The search query"
          }
        },
        required: ["query"]
      }
    }
  }
];

const stream = await ollama.chat({
  model: "llama3.2:3b",
  messages: [
    { role: "user", content: "Search for install ollama models" }
  ],
  tools: tools,
  stream: true
});

for await (const chunk of stream) {
  console.log("Content:", chunk.message?.content);
  console.log("Tool calls:", chunk.message?.tool_calls);
}

Environment

  • Ollama npm library version: 0.6.3
  • Model: llama3.2:3b
  • Node.js version: >=25.0.0

Additional Context

  • Other models (e.g., gpt-oss, llama3.2:8b) correctly return tool calls in the tool_calls field
  • The issue occurs consistently when tools are included in the request
  • The JSON output in content is properly formatted and parseable, but it's not using the expected tool_calls mechanism

Debug Output Example

When tools are included, the response chunks show:

{
  "role": "assistant",
  "content": "```json\n{\"name\": \"query_web_search\", \"parameters\": {\"query\": \"install ollama models\"}}\n```",
  "tool_calls": null
}

Expected format (as seen with other models):

{
  "role": "assistant",
  "content": "",
  "tool_calls": [
    {
      "id": "call_xxx",
      "function": {
        "name": "query_web_search",
        "arguments": {
          "query": "install ollama models"
        }
      }
    }
  ]
}

Relevant log output


OS

Linux, macOS, Docker

GPU

Nvidia, Apple, Intel

CPU

Apple, Intel

Ollama version

0.13.4

Originally created by @sacenox on GitHub (Dec 18, 2025). Original GitHub issue: https://github.com/ollama/ollama/issues/13519 ### What is the issue? # llama3.2:3b outputs tool calls as JSON in content instead of using tool_calls field ## Description When using `llama3.2:3b` with the Ollama npm library and including tools in the request, the model outputs tool calls as JSON text in the `content` field instead of using the `tool_calls` field like other models do. ## Expected Behavior The model should return tool calls in the `tool_calls` field of the response, similar to how other models (e.g., `gpt-oss:latest`) handle tool calling. ## Actual Behavior The model outputs tool calls as JSON text in the `content` field, wrapped in code blocks: ```json {"name": "query_web_search", "parameters": {"query": "install ollama models"}} ``` The `tool_calls` field is empty or not present in the response chunks. ## Steps to Reproduce 1. Use Ollama npm library version `0.6.3` 2. Send a chat request to `llama3.2:3b` model with tools included 3. Observe the response - tool calls appear as JSON in `content` instead of `tool_calls` Example code: ```javascript import ollama from "ollama"; const tools = [ { type: "function", function: { name: "query_web_search", description: "Perform a web search", parameters: { type: "object", properties: { query: { type: "string", description: "The search query" } }, required: ["query"] } } } ]; const stream = await ollama.chat({ model: "llama3.2:3b", messages: [ { role: "user", content: "Search for install ollama models" } ], tools: tools, stream: true }); for await (const chunk of stream) { console.log("Content:", chunk.message?.content); console.log("Tool calls:", chunk.message?.tool_calls); } ``` ## Environment - Ollama npm library version: `0.6.3` - Model: `llama3.2:3b` - Node.js version: `>=25.0.0` ## Additional Context - Other models (e.g., `gpt-oss`, `llama3.2:8b`) correctly return tool calls in the `tool_calls` field - The issue occurs consistently when tools are included in the request - The JSON output in content is properly formatted and parseable, but it's not using the expected `tool_calls` mechanism ## Debug Output Example When tools are included, the response chunks show: ```json { "role": "assistant", "content": "```json\n{\"name\": \"query_web_search\", \"parameters\": {\"query\": \"install ollama models\"}}\n```", "tool_calls": null } ``` Expected format (as seen with other models): ```json { "role": "assistant", "content": "", "tool_calls": [ { "id": "call_xxx", "function": { "name": "query_web_search", "arguments": { "query": "install ollama models" } } } ] } ``` ### Relevant log output ```shell ``` ### OS Linux, macOS, Docker ### GPU Nvidia, Apple, Intel ### CPU Apple, Intel ### Ollama version 0.13.4
GiteaMirror added the bug label 2026-04-29 09:09:21 -05:00
Author
Owner

@rick-github commented on GitHub (Dec 18, 2025):

Works fine via direct call:

$ curl -s localhost:11434/api/chat -d '{
  "model":"llama3.2:3b",
  "messages":[
    {"role":"user","content":"Search for install ollama models"}
  ],
  "tools":[{
    "type":"function",
    "function":{
      "name":"query_web_search",
      "description":"Perform a web search",
      "parameters":{
        "type":"object",
        "properties":{
          "query":{
            "type":"string",
            "description":"The search query"
          }
        },
        "required":["query"]
      }
    }
  }],
  "stream":false
}' | jq
{
  "model": "llama3.2:3b",
  "created_at": "2025-12-18T14:28:33.538565768Z",
  "message": {
    "role": "assistant",
    "content": "",
    "tool_calls": [
      {
        "id": "call_5nccbtr4",
        "function": {
          "index": 0,
          "name": "query_web_search",
          "arguments": {
            "query": "install olamma models"
          }
        }
      }
    ]
  },
  "done": true,
  "done_reason": "stop",
  "total_duration": 686997782,
  "load_duration": 271693268,
  "prompt_eval_count": 161,
  "prompt_eval_duration": 20326815,
  "eval_count": 21,
  "eval_duration": 381376036
}

The tool call in content looks well-formed but is not recognized by the tool call parser, which may indicate an issue with the template. What's the output of

ollama show --template llama3.2:3b

<!-- gh-comment-id:3670595036 --> @rick-github commented on GitHub (Dec 18, 2025): Works fine via direct call: ```console $ curl -s localhost:11434/api/chat -d '{ "model":"llama3.2:3b", "messages":[ {"role":"user","content":"Search for install ollama models"} ], "tools":[{ "type":"function", "function":{ "name":"query_web_search", "description":"Perform a web search", "parameters":{ "type":"object", "properties":{ "query":{ "type":"string", "description":"The search query" } }, "required":["query"] } } }], "stream":false }' | jq ``` ```json { "model": "llama3.2:3b", "created_at": "2025-12-18T14:28:33.538565768Z", "message": { "role": "assistant", "content": "", "tool_calls": [ { "id": "call_5nccbtr4", "function": { "index": 0, "name": "query_web_search", "arguments": { "query": "install olamma models" } } } ] }, "done": true, "done_reason": "stop", "total_duration": 686997782, "load_duration": 271693268, "prompt_eval_count": 161, "prompt_eval_duration": 20326815, "eval_count": 21, "eval_duration": 381376036 } ``` The tool call in `content` looks well-formed but is not recognized by the tool call parser, which may indicate an issue with the template. What's the output of ``` ollama show --template llama3.2:3b ```
Author
Owner

@sacenox commented on GitHub (Dec 18, 2025):

Here's the output of the ollama show command:

❯ ollama show --template llama3.2:3b
<|start_header_id|>system<|end_header_id|>

Cutting Knowledge Date: December 2023

{{ if .System }}{{ .System }}
{{- end }}
{{- if .Tools }}When you receive a tool call response, use the output to format an answer to the orginal user question.

You are a helpful assistant with tool calling capabilities.
{{- end }}<|eot_id|>
{{- range $i, $_ := .Messages }}
{{- $last := eq (len (slice $.Messages $i)) 1 }}
{{- if eq .Role "user" }}<|start_header_id|>user<|end_header_id|>
{{- if and $.Tools $last }}

Given the following functions, please respond with a JSON for a function call with its proper arguments that best answers the given prompt.

Respond in the format {"name": function name, "parameters": dictionary of argument name and its value}. Do not use variables.

{{ range $.Tools }}
{{- . }}
{{ end }}
{{ .Content }}<|eot_id|>
{{- else }}

{{ .Content }}<|eot_id|>
{{- end }}{{ if $last }}<|start_header_id|>assistant<|end_header_id|>

{{ end }}
{{- else if eq .Role "assistant" }}<|start_header_id|>assistant<|end_header_id|>
{{- if .ToolCalls }}
{{ range .ToolCalls }}
{"name": "{{ .Function.Name }}", "parameters": {{ .Function.Arguments }}}{{ end }}
{{- else }}

{{ .Content }}
{{- end }}{{ if not $last }}<|eot_id|>{{ end }}
{{- else if eq .Role "tool" }}<|start_header_id|>ipython<|end_header_id|>

{{ .Content }}<|eot_id|>{{ if $last }}<|start_header_id|>assistant<|end_header_id|>

{{ end }}
{{- end }}
{{- end }}%

I've also been able to run the same cURL call:

❯ curl -s localhost:11434/api/chat -d '{
  "model":"llama3.2:3b",
  "messages":[
    {"role":"user","content":"Search for install ollama models"}
  ],
  "tools":[{
    "type":"function",
    "function":{
      "name":"query_web_search",
      "description":"Perform a web search",
      "parameters":{
        "type":"object",
        "properties":{
          "query":{
            "type":"string",
            "description":"The search query"
          }
        },
        "required":["query"]
      }
    }
  }],
  "stream":false
}' | jq
{
  "model": "llama3.2:3b",
  "created_at": "2025-12-18T15:29:10.304027Z",
  "message": {
    "role": "assistant",
    "content": "",
    "tool_calls": [
      {
        "id": "call_h8ikz9yn",
        "function": {
          "index": 0,
          "name": "query_web_search",
          "arguments": {
            "query": "install ollama models"
          }
        }
      }
    ]
  },
  "done": true,
  "done_reason": "stop",
  "total_duration": 3659757167,
  "load_duration": 2690591833,
  "prompt_eval_count": 161,
  "prompt_eval_duration": 407400667,
  "eval_count": 22,
  "eval_duration": 548841582
}
<!-- gh-comment-id:3670864588 --> @sacenox commented on GitHub (Dec 18, 2025): Here's the output of the ollama show command: ``` ❯ ollama show --template llama3.2:3b <|start_header_id|>system<|end_header_id|> Cutting Knowledge Date: December 2023 {{ if .System }}{{ .System }} {{- end }} {{- if .Tools }}When you receive a tool call response, use the output to format an answer to the orginal user question. You are a helpful assistant with tool calling capabilities. {{- end }}<|eot_id|> {{- range $i, $_ := .Messages }} {{- $last := eq (len (slice $.Messages $i)) 1 }} {{- if eq .Role "user" }}<|start_header_id|>user<|end_header_id|> {{- if and $.Tools $last }} Given the following functions, please respond with a JSON for a function call with its proper arguments that best answers the given prompt. Respond in the format {"name": function name, "parameters": dictionary of argument name and its value}. Do not use variables. {{ range $.Tools }} {{- . }} {{ end }} {{ .Content }}<|eot_id|> {{- else }} {{ .Content }}<|eot_id|> {{- end }}{{ if $last }}<|start_header_id|>assistant<|end_header_id|> {{ end }} {{- else if eq .Role "assistant" }}<|start_header_id|>assistant<|end_header_id|> {{- if .ToolCalls }} {{ range .ToolCalls }} {"name": "{{ .Function.Name }}", "parameters": {{ .Function.Arguments }}}{{ end }} {{- else }} {{ .Content }} {{- end }}{{ if not $last }}<|eot_id|>{{ end }} {{- else if eq .Role "tool" }}<|start_header_id|>ipython<|end_header_id|> {{ .Content }}<|eot_id|>{{ if $last }}<|start_header_id|>assistant<|end_header_id|> {{ end }} {{- end }} {{- end }}% ``` I've also been able to run the same cURL call: ``` ❯ curl -s localhost:11434/api/chat -d '{ "model":"llama3.2:3b", "messages":[ {"role":"user","content":"Search for install ollama models"} ], "tools":[{ "type":"function", "function":{ "name":"query_web_search", "description":"Perform a web search", "parameters":{ "type":"object", "properties":{ "query":{ "type":"string", "description":"The search query" } }, "required":["query"] } } }], "stream":false }' | jq { "model": "llama3.2:3b", "created_at": "2025-12-18T15:29:10.304027Z", "message": { "role": "assistant", "content": "", "tool_calls": [ { "id": "call_h8ikz9yn", "function": { "index": 0, "name": "query_web_search", "arguments": { "query": "install ollama models" } } } ] }, "done": true, "done_reason": "stop", "total_duration": 3659757167, "load_duration": 2690591833, "prompt_eval_count": 161, "prompt_eval_duration": 407400667, "eval_count": 22, "eval_duration": 548841582 } ```
Author
Owner

@sacenox commented on GitHub (Dec 18, 2025):

I'm going to close this issue and apologize for any time wasted. It was a bug with the frontend UI render logic... 🤦

Thank you for your time and help 🙇

<!-- gh-comment-id:3671013939 --> @sacenox commented on GitHub (Dec 18, 2025): I'm going to close this issue and apologize for any time wasted. It was a bug with the frontend UI render logic... 🤦 Thank you for your time and help 🙇
Author
Owner

@johnnymast commented on GitHub (Jan 9, 2026):

This is still happening to this day with llama3.2. My chatbot randomly spits out toolcalls that are not send to tool_calls but to content. This results in that she will talk json randomly. Now i am aware there might be issues with the model but i am not 100% sure of this because i am not techical enough to know under the hood.

<!-- gh-comment-id:3727552494 --> @johnnymast commented on GitHub (Jan 9, 2026): This is still happening to this day with llama3.2. My chatbot randomly spits out toolcalls that are not send to tool_calls but to content. This results in that she will talk json randomly. Now i am aware there might be issues with the model but i am not 100% sure of this because i am not techical enough to know under the hood.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: github-starred/ollama#55420