Skip to content

fix: parse empty tool call arguments in the non-streaming OpenAI generators - #13047

Merged
sjrl merged 1 commit into
deepset-ai:mainfrom
chrikrah:fix/openai-zero-argument-tool-call
Oct 5, 2026
Merged

sjrl merged 1 commit into
deepset-ai:mainfrom
chrikrah:fix/openai-zero-argument-tool-call

Conversation

@chrikrah

@chrikrah chrikrah commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Related Issues

Proposed Changes:

openai.py:671 and openai_responses.py:695 call json.loads on the arguments of each tool call. OpenAI-compatible servers such as vLLM send "" for a tool with no parameters (vllm-project/vllm#19419); None is covered as a defensive case. The converter then drops the call with the "malformed JSON" warning, or the reply raises TypeError. Both streaming paths already turn "" into {}.

Both sites now use _parse_openai_tool_call_arguments from #12790. Malformed JSON is still skipped. A call cut off at finish_reason: length with empty arguments now becomes {}, as it already does when streaming, and _check_finish_reason still logs the truncation on Chat Completions.

How did you test it?

One parametrized test per generator, for "" and None.

$ PYTHONPATH=. python -m pytest test/components/generators/chat/test_openai.py test/components/generators/chat/test_azure.py \
    test/components/generators/chat/test_openai_responses.py test/components/generators/chat/test_openai_responses_conversion.py \
    test/components/generators/chat/test_azure_responses.py -m 'not integration' -q
main 0499239:                          174 passed, 40 deselected
this branch:                           178 passed, 40 deselected
both production files reverted:        4 failed, 174 passed

$ ruff check && ruff format --check    # ruff 0.16.9, four touched files: clean
$ mypy --python-version 3.12 haystack/components/generators/chat/openai.py haystack/components/generators/chat/openai_responses.py
Success: no issues found in 2 source files   # mypy 2.3.1
# not run: integration tests, no server was called

Notes for the reviewer

The Azure generators inherit both methods.

Checklist

  • I have read the contributors guidelines and the code of conduct.
  • I have updated the related issue with new insights and changes: there is no issue for this path.
  • I have added unit tests and updated the docstrings.
  • I have used one of the conventional commit types for my PR title.
  • I have documented my code: the two-line change needs no new docstring.
  • I have added a release note file.
  • I have run pre-commit hooks: ruff and mypy ran directly, as quoted above, and the full pre-commit set did not.

@sjrl, you merged #12790 and kept invalid JSON raising. The string "null" still parses to None and becomes ToolCall.arguments. Should the helper map it to {} too?

@chrikrah
chrikrah requested a review from a team as a code owner October 1, 2026 00:16
@chrikrah
chrikrah requested review from sjrl and removed request for a team October 1, 2026 00:16
@vercel

vercel Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

@chrikrah is attempting to deploy a commit to the deepset Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions

github-actions Bot commented Oct 1, 2026

Copy link
Copy Markdown
Contributor

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  haystack/components/generators/chat
  openai.py
  openai_responses.py
Project Total  

This report was generated by python-coverage-comment-action

@sjrl sjrl self-assigned this Oct 5, 2026

@sjrl sjrl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@sjrl
sjrl merged commit da21242 into deepset-ai:main Oct 5, 2026
27 of 28 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants