openclaw - ✅(Solved) Fix [Bug]:Ollama tool_call arguments not deserialized — tool invocations lose parameters [1 pull requests, 1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
openclaw/openclaw#69735Fetched 2026-04-22 07:48:59
View on GitHub
Comments
0
Participants
1
Timeline
3
Reactions
0
Participants
Timeline (top)
cross-referenced ×1labeled ×1referenced ×1

Ollama returns tool_call arguments as a JSON string, but OpenClaw's buildAssistantMessage passes it directly to downstream handlers without JSON.parse, causing arguments to be lost or treated as [object Object].

Root Cause

Root cause confirmed in stream-DqNCFbiN.js line 369:

Fix Action

Fixed

PR fix notes

PR #69751: fix(ollama): deserialize string tool_call arguments in buildAssistantMessage

Description (problem / solution / changelog)

Problem

Ollama returns tool_call arguments as a JSON string when using some models (e.g. gemma4:26b). buildAssistantMessage previously passed the raw string directly to downstream handlers, causing tool invocations to receive broken text or fail entirely.

Solution

Wrap toolCall.function.arguments with ensureArgsObject(), which JSON.parses string arguments and passes objects through unchanged.

Changes

  • extensions/ollama/src/stream.ts: Use ensureArgsObject() when building toolCall content
  • extensions/ollama/src/stream.test.ts: Add tests for string and object argument parsing

Linked Issue

  • Fixes #69735

Change Type

  • Bug fix

Scope

  • Ollama provider

Testing

  • Added unit tests covering both string JSON arguments and object arguments
  • All existing tests pass

Changed files

  • extensions/ollama/src/stream.test.ts (modified, +37/-1)
  • extensions/ollama/src/stream.ts (modified, +2/-2)
  • src/auto-reply/reply/commands-models.test.ts (modified, +8/-0)
  • src/auto-reply/reply/commands-models.ts (modified, +1/-1)
  • ui/src/ui/markdown.test.ts (modified, +5/-0)
  • ui/src/ui/markdown.ts (modified, +7/-2)

Code Example

Root cause confirmed in stream-DqNCFbiN.js line 369:

Fix applied (backup saved as stream-DqNCFbiN.js.bak):

- arguments: toolCall.function.arguments,
+ arguments: typeof toolCall.function.arguments === "string" 
+   ? JSON.parse(toolCall.function.arguments) 
+   : toolCall.function.arguments,
RAW_BUFFERClick to expand / collapse

Bug type

Behavior bug (incorrect output/state without crash)

Beta release blocker

No

Summary

Ollama returns tool_call arguments as a JSON string, but OpenClaw's buildAssistantMessage passes it directly to downstream handlers without JSON.parse, causing arguments to be lost or treated as [object Object].

Steps to reproduce

  1. Configure ollama/gemma4:26b (or any Ollama model) as primary or fallback model
  2. Ask the model to perform a local file operation (e.g. "list my workspace")
  3. Observe that exec tool is called but arguments are empty/undefined

Expected behavior

Tool calls should receive correctly parsed arguments as an object (e.g. {command: "ls ~/Desktop"}), not a JSON string.

Actual behavior

Tool invocation fails or parameters are undefined. Ollama API returns arguments as a string: "{"command": "ls", "path": "/Users/..."}" Without deserialization, downstream handlers receive the raw string instead of a parsed object.

OpenClaw version

2026.4.8

Operating system

macOS 26.4.1

Install method

npm global

Model

ollama/gemma4:26b

Provider / routing chain

openclaw -> ollama (localhost:11434)

Additional provider/model setup details

No response

Logs, screenshots, and evidence

Root cause confirmed in stream-DqNCFbiN.js line 369:

Fix applied (backup saved as stream-DqNCFbiN.js.bak):

- arguments: toolCall.function.arguments,
+ arguments: typeof toolCall.function.arguments === "string" 
+   ? JSON.parse(toolCall.function.arguments) 
+   : toolCall.function.arguments,

Impact and severity

Affected: All Ollama model users who rely on tool_calls (exec, read, write, etc.) Severity: High — tool calls silently fail or receive undefined parameters Frequency: 100% of Ollama tool invocations Consequence: Models cannot perform local file operations despite having the tools available

Additional information

This is a provider-contract mismatch: Ollama's API spec defines arguments as string (per Ollama API format), while OpenClaw's downstream handlers expect a native JSON object. The fix is a one-line type guard + parse. Fix is backward-compatible: if arguments is already an object, it passes through unchanged.

extent analysis

TL;DR

Apply a type guard and JSON.parse to the toolCall.function.arguments in OpenClaw's buildAssistantMessage to correctly parse the arguments passed from Ollama.

Guidance

  • Verify that the issue is resolved by checking the logs for successful tool invocations with correctly parsed arguments.
  • Test the fix with different Ollama models and tool calls to ensure backward compatibility.
  • Review the OpenClaw codebase for similar provider-contract mismatches that may cause similar issues.
  • Consider updating the OpenClaw documentation to reflect the expected format of toolCall.function.arguments to prevent similar issues in the future.

Example

arguments: typeof toolCall.function.arguments === "string" 
  ? JSON.parse(toolCall.function.arguments) 
  : toolCall.function.arguments,

Notes

The provided fix is specific to the OpenClaw version 2026.4.8 and may not apply to other versions. Additionally, this fix assumes that the toolCall.function.arguments is always a valid JSON string when passed from Ollama.

Recommendation

Apply the workaround by adding the type guard and JSON.parse to the toolCall.function.arguments in OpenClaw's buildAssistantMessage, as this is a backward-compatible fix that resolves the provider-contract mismatch.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Tool calls should receive correctly parsed arguments as an object (e.g. {command: "ls ~/Desktop"}), not a JSON string.

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING