fix: encode empty tool arguments as JSON object instead of array#896
Open
MaximeWillinger wants to merge 1 commit intoprism-php:mainfrom
Open
fix: encode empty tool arguments as JSON object instead of array#896MaximeWillinger wants to merge 1 commit intoprism-php:mainfrom
MaximeWillinger wants to merge 1 commit intoprism-php:mainfrom
Conversation
When a tool has no parameters, `$toolCall->arguments()` returns an
empty PHP array. `json_encode([])` produces `"[]"` (JSON array),
but providers expect `"{}"` (JSON object) for the `arguments` field.
This causes errors like "input should be a valid dictionary" when
providers (e.g. OpenRouter → Anthropic) validate the tool call input.
Using `$toolCall->arguments() ?: (object) []` ensures empty arguments
are always encoded as `"{}"`.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
When using multi-step tool calling with tools that have no parameters, the second request fails because empty tool arguments are encoded as a JSON array (
"[]") instead of a JSON object ("{}").This causes provider-side validation errors. For example, OpenRouter (which translates to Anthropic format internally) returns:
Reproduction
This happens in any multi-step tool calling scenario where a tool has no parameters:
When the model calls this tool during streaming, Prism's
Streamhandler:arguments: "{}"from the modeljson_decode("{}", true)which returns[](empty PHP array)ToolCallvalue objectMessageMapre-encodes it withjson_encode([])which produces"[]"The provider then rejects
"[]"because function arguments must be a JSON object, not an array.Root cause
This is a PHP-specific ambiguity: an empty PHP array
[]is both a valid list and a valid dictionary.json_encode([])produces"[]"(JSON array), but the OpenAI API specification requires function arguments to always be a JSON object string.Solution
Use
json_encode($toolCall->arguments() ?: (object) [])to ensure empty arguments are encoded as"{}". When arguments are non-empty, the?:operator short-circuits and behavior is unchanged.Affected providers
The same pattern existed in all providers that encode tool call arguments in
MessageMap:All six have been fixed with the same one-line change, along with a corresponding test for each.