Bug Description
When using the OpenRouter provider with an Anthropic model (e.g. anthropic/claude-sonnet-4.6), multi-step tool calls fail with:
OpenRouter Bad Request: messages.3.content.3.tool_use.input: Input should be a valid dictionary
This happens when a tool is called with no arguments (empty {}).
Root Cause
In src/Providers/OpenRouter/Maps/MessageMap.php:162, tool call arguments are serialized as:
'arguments' => json_encode($toolCall->arguments()),
When a tool has no arguments:
$toolCall->arguments() returns [] (PHP empty array)
json_encode([]) produces "[]" (JSON array)
- OpenRouter translates this to Anthropic's
input: []
- Anthropic rejects it because
input must be a dictionary (object), not an array
This is a PHP limitation — json_decode("{}", true) returns [], and json_encode([]) returns "[]" instead of "{}".
The Anthropic Provider Already Handles This
The Anthropic provider in src/Providers/Anthropic/Maps/MessageMap.php:163 correctly handles this case:
'input' => $toolCall->arguments() === [] ? new \stdClass : $toolCall->arguments(),
The OpenRouter provider is missing this safeguard.
Reproduction
- Configure Prism with OpenRouter provider routing to an Anthropic model
- Register a tool that accepts no required arguments (e.g. a "list all users" tool)
- Send a prompt that triggers the tool, then requires a follow-up step (multi-step tool use)
- The second API call fails because the accumulated assistant message contains
"arguments": "[]" instead of "arguments": "{}"
Suggested Fix
In src/Providers/OpenRouter/Maps/MessageMap.php, change:
'arguments' => json_encode($toolCall->arguments()),
To:
'arguments' => json_encode($toolCall->arguments() === [] ? new \stdClass : $toolCall->arguments()),
This matches the existing pattern in the Anthropic provider.
Note: The same issue likely exists in other providers that use json_encode($toolCall->arguments()):
src/Providers/XAI/Maps/MessageMap.php
src/Providers/Mistral/Maps/MessageMap.php
src/Providers/Groq/Maps/MessageMap.php
src/Providers/DeepSeek/Maps/MessageMap.php
We'd be happy to provide a PR for this fix.
Environment
- prism-php/prism: v0.99.19
- laravel/ai: ^0.1.3
- PHP: 8.4
- Provider: OpenRouter → anthropic/claude-sonnet-4.6
Bug Description
When using the OpenRouter provider with an Anthropic model (e.g.
anthropic/claude-sonnet-4.6), multi-step tool calls fail with:This happens when a tool is called with no arguments (empty
{}).Root Cause
In
src/Providers/OpenRouter/Maps/MessageMap.php:162, tool call arguments are serialized as:When a tool has no arguments:
$toolCall->arguments()returns[](PHP empty array)json_encode([])produces"[]"(JSON array)input: []inputmust be a dictionary (object), not an arrayThis is a PHP limitation —
json_decode("{}", true)returns[], andjson_encode([])returns"[]"instead of"{}".The Anthropic Provider Already Handles This
The Anthropic provider in
src/Providers/Anthropic/Maps/MessageMap.php:163correctly handles this case:The OpenRouter provider is missing this safeguard.
Reproduction
"arguments": "[]"instead of"arguments": "{}"Suggested Fix
In
src/Providers/OpenRouter/Maps/MessageMap.php, change:To:
This matches the existing pattern in the Anthropic provider.
Note: The same issue likely exists in other providers that use
json_encode($toolCall->arguments()):src/Providers/XAI/Maps/MessageMap.phpsrc/Providers/Mistral/Maps/MessageMap.phpsrc/Providers/Groq/Maps/MessageMap.phpsrc/Providers/DeepSeek/Maps/MessageMap.phpWe'd be happy to provide a PR for this fix.
Environment