Skip to content

Return {} for empty-string tool-call arguments in the interactions protocol - #911

Closed
pcbeingused333 wants to merge 1 commit into
crmne:mainfrom
pcbeingused333:fix/interactions-empty-tool-args
Closed

pcbeingused333 wants to merge 1 commit into
crmne:mainfrom
pcbeingused333:fix/interactions-empty-tool-args

Conversation

@pcbeingused333

Copy link
Copy Markdown

Problem

Protocols::Interactions::Tools.parse_interaction_arguments runs JSON.parse on any String:

def parse_interaction_arguments(arguments)
  arguments.is_a?(String) ? JSON.parse(arguments) : arguments || {}
rescue JSON::ParserError => e
  raise ToolCallParseError.new(finish_reason: :tool_calls), cause: e
end

A function_call step whose arguments is an empty string ("") makes JSON.parse("") raise, so the whole run fails with ToolCallParseError for what is a valid zero-argument tool call.

The sibling parser already handles this — Protocols::ChatCompletions::Tools.parse_tool_call_arguments:

if arguments.nil? || arguments.empty?
  {}
else
  JSON.parse(arguments)
end

So the two tool-call parsers disagree on the same input.

Fix

Guard empty (and nil) arguments in parse_interaction_arguments the same way, before JSON.parse.

return {} if arguments.nil? || (arguments.is_a?(String) && arguments.empty?)

Tests

New spec/ruby_llm/protocols/interactions/tools_spec.rb: empty string → {}, missing key → {}, Hash passthrough, valid JSON object, malformed JSON → ToolCallParseError. The empty-string case raises on main.

bundle exec rspec spec/ruby_llm/protocols/interactions{_spec.rb,/tools_spec.rb} spec/ruby_llm/protocols/chat_completions/tools_spec.rb — green; rubocop clean on both files.

…otocol

Protocols::Interactions::Tools.parse_interaction_arguments ran
JSON.parse on any String, so a function_call step with
"arguments": "" raised ToolCallParseError and failed the whole run.
Protocols::ChatCompletions::Tools.parse_tool_call_arguments already
guards this with `arguments.nil? || arguments.empty?` -> {}; mirror it
so the two tool-call parsers agree.

Adds spec/ruby_llm/protocols/interactions/tools_spec.rb covering empty
string, missing key, hash passthrough, valid JSON, and malformed JSON.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018uqJtTJWawYLVA5EdpUmho
@codecov

codecov Bot commented Sep 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 94.65%. Comparing base (2d16ed6) to head (41fb5ae).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #911      +/-   ##
==========================================
+ Coverage   94.64%   94.65%   +0.01%     
==========================================
  Files         312      312              
  Lines       15198    15199       +1     
  Branches     2710     2711       +1     
==========================================
+ Hits        14384    14387       +3     
+ Misses        310      309       -1     
+ Partials      504      503       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

crmne added a commit that referenced this pull request Sep 13, 2026
Treat an empty argument string as a zero-argument tool call while
preserving errors for malformed JSON.

Integrates #911.
@crmne

crmne commented Sep 13, 2026

Copy link
Copy Markdown
Owner

Integrated in c4b3afc3. Thanks for the fix and regression specs.

@crmne crmne closed this Sep 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants