You set up OpenClaw with Ollama, tested it, and it seemed to work. Then you asked it to do something multi-step — search a file, then summarize the result, then write it somewhere — and things got weird. The agent described what it would do instead of doing it. Or it called the right tool with obviously wrong parameters. Or it just stopped mid-chain.

This is a known bug in OpenClaw's Ollama native provider (GitHub issue #57103): tool call arguments are incorrectly stringified as a string instead of passed as a JSON object. In single-turn interactions it often goes unnoticed. In multi-turn tool chains, it compounds into silent failures and corrupted parameters.

Affected: Any setup using Ollama as the provider via the native Ollama API (api: "ollama-completions" or similar). The OpenAI-compatible endpoint workaround (below) does not have this bug.

How to Tell If This Is Your Problem

You can confirm by checking your agent logs. Run OpenClaw with verbose output:

openclaw gateway start --verbose 2>&1 | grep -i "tool"

If you see tool arguments wrapped in extra string quotes ("{...}" instead of {...}), you've confirmed the bug.

What's Actually Happening

When Ollama returns a tool call from a local model, it sends back the arguments as a JSON object. OpenClaw's Ollama native provider then takes those arguments and — due to a serialization bug — wraps them in an extra JSON.stringify() call. The result:

Expected (correct)

{
  "name": "read_file",
  "arguments": {
    "path": "/workspace/notes.md"
  }
}

What Ollama provider sends

{
  "name": "read_file",
  "arguments": "{\"path\":\"/workspace/notes.md\"}"
}

OpenClaw's tool dispatcher then tries to parse the arguments but receives a string instead of an object. In turn 1, the model often recovers. By turn 2 or 3, the conversation history contains malformed tool results, and the model starts hallucinating what tools returned or stops calling them entirely.

The Fix — Switch to OpenAI-Compatible Endpoint

Ollama exposes an OpenAI-compatible API at http://localhost:11434/v1. This endpoint does not have the stringification bug because it uses a different serialization path. Switching to it fixes multi-turn tool calling completely.

In your ~/.openclaw/openclaw.json, change your Ollama provider config:

# Before (Ollama native — has the bug)
"providers": {
  "ollama": {
    "baseUrl": "http://127.0.0.1:11434",
    "api": "ollama-completions"
  }
}

# After (OpenAI-compatible — no bug)
"providers": {
  "ollama": {
    "baseUrl": "http://127.0.0.1:11434/v1",
    "apiKey": "ollama",
    "api": "openai-completions"
  }
}

The key changes:

Then restart:

openclaw gateway restart

This works with all Ollama models — Qwen, Llama, Gemma, Mistral, etc. The OpenAI-compatible endpoint supports the same models, just through a different API path that handles tool calling correctly.

If You Want to Keep Using the Native Provider

The native provider has one small advantage: it supports some Ollama-specific parameters (like num_ctx for context window size) that the OpenAI-compatible endpoint doesn't always honor. If that matters to you, there's a partial workaround:

Set injectNumCtxForOpenAICompat: true in your provider config. OpenClaw will inject the context window size as a custom parameter even through the OpenAI-compatible endpoint:

"providers": {
  "ollama": {
    "baseUrl": "http://127.0.0.1:11434/v1",
    "apiKey": "ollama",
    "api": "openai-completions",
    "injectNumCtxForOpenAICompat": true,
    "models": [
      {
        "id": "qwen3.5:9b",
        "contextWindow": 32768
      }
    ]
  }
}

The native provider bug is tracked at GitHub issue #57103. A fix is in review. Once it lands (likely in a future 4.x release), you can switch back to the native provider if you prefer — but the OpenAI-compatible path works great and there's no real reason to switch back.

Which Local Models Actually Work Well for Tool Calling?

Even with the provider bug fixed, model capability matters. Not all local models handle tool calling reliably:

For a NUC or mini-PC with 14–16GB RAM, Qwen 3.5 9B via the OpenAI-compatible endpoint is the sweet spot: free, fast enough, and reliable tool calling.