Skip to content

fix: handle empty or missing tool-call arguments in from_openai_dict_format#11972

Open
chuenchen309 wants to merge 5 commits into
deepset-ai:mainfrom
chuenchen309:fix/openai-toolcall-empty-arguments
Open

fix: handle empty or missing tool-call arguments in from_openai_dict_format#11972
chuenchen309 wants to merge 5 commits into
deepset-ai:mainfrom
chuenchen309:fix/openai-toolcall-empty-arguments

Conversation

@chuenchen309

Copy link
Copy Markdown
Contributor

Problem

ChatMessage.from_openai_dict_format parses tool-call arguments with:

arguments=json.loads(tc["function"]["arguments"])

This assumes arguments is always present and always a valid JSON string. A
zero-argument tool call from an OpenAI-compatible server (vLLM, llama.cpp,
Ollama, LM Studio, ...) commonly sends an empty string, null, or omits the key:

# empty string  -> json.JSONDecodeError
{"id": "1", "function": {"name": "now", "arguments": ""}}
# missing key   -> KeyError('arguments')
{"id": "1", "function": {"name": "now"}}

_validate_openai_message only checks that a function field exists, so nothing
guards this — and the method's docstring explicitly courts these "shallow
OpenAI-compatible APIs".

Fix

Treat empty/null/missing arguments as an empty dict, leaving valid-JSON parsing
unchanged:

raw_arguments = tc["function"].get("arguments")
arguments = json.loads(raw_arguments) if raw_arguments else {}

Tests

Added two tests in test/dataclasses/test_chat_message.py (empty-string and
missing-key arguments). Both fail before the change (JSONDecodeError /
KeyError) and pass after. All 15 from_openai_dict_format tests pass.

$ python -m pytest test/dataclasses/test_chat_message.py -k from_openai_dict_format
15 passed

ruff check / ruff format --check pass. Added a release note.


Disclosure: I used AI assistance (Claude) to find this crash-on-edge-input and
draft the tests. I reviewed the change, ran the suite, and take responsibility
for its correctness.

@chuenchen309 chuenchen309 requested a review from a team as a code owner July 13, 2026 01:32
@chuenchen309 chuenchen309 requested review from bogdankostic and removed request for a team July 13, 2026 01:32
@vercel

vercel Bot commented Jul 13, 2026

Copy link
Copy Markdown

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

A member of the Team first needs to authorize it.

@CLAassistant

CLAassistant commented Jul 13, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@github-actions github-actions Bot added topic:tests type:documentation Improvements on the docs labels Jul 13, 2026

@bogdankostic bogdankostic 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 for the PR @chuenchen309. It already looks good in principle, we just need to update the release notes.

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.

This release note doesn't seem to be related to the changes made in this PR.

Comment on lines +4 to +8
Fixed `ChatMessage.from_openai_dict_format` crashing on zero-argument tool
calls. OpenAI-compatible servers (vLLM, llama.cpp, Ollama, LM Studio, ...) may
send an empty string or omit the `arguments` field for a tool call that takes
no arguments; this previously raised `json.JSONDecodeError` or `KeyError`.
Such tool calls are now parsed into a `ToolCall` with empty `arguments`.

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.

We need to use double-backticks for in-line code in release notes.

Suggested change
Fixed `ChatMessage.from_openai_dict_format` crashing on zero-argument tool
calls. OpenAI-compatible servers (vLLM, llama.cpp, Ollama, LM Studio, ...) may
send an empty string or omit the `arguments` field for a tool call that takes
no arguments; this previously raised `json.JSONDecodeError` or `KeyError`.
Such tool calls are now parsed into a `ToolCall` with empty `arguments`.
Fixed ``ChatMessage.from_openai_dict_format`` crashing on zero-argument tool
calls. OpenAI-compatible servers (vLLM, llama.cpp, Ollama, LM Studio, ...) may
send an empty string or omit the ``arguments`` field for a tool call that takes
no arguments; this previously raised ``json.JSONDecodeError`` or ``KeyError``.
Such tool calls are now parsed into a ``ToolCall`` with empty ``arguments``.

@github-actions

Copy link
Copy Markdown
Contributor

Coverage report

Click to see where and how coverage changed

FileStatementsMissingCoverageCoverage
(new stmts)
Lines missing
  haystack/dataclasses
  chat_message.py
Project Total  

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

chuenchen309 and others added 5 commits July 15, 2026 22:36
…format

`ChatMessage.from_openai_dict_format` did `json.loads(tc["function"]["arguments"])`,
assuming `arguments` is always present and a valid JSON string. Zero-argument tool
calls from OpenAI-compatible servers (vLLM, llama.cpp, Ollama, LM Studio, ...)
send an empty string, null, or omit the key entirely, which raised
`json.JSONDecodeError` or `KeyError` — even though the method docstring courts
these 'shallow OpenAI-compatible APIs'. The message validator only checks that a
`function` field exists, so nothing guarded this.

Treat empty/null/missing arguments as an empty dict, leaving valid-JSON parsing
unchanged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@chuenchen309 chuenchen309 force-pushed the fix/openai-toolcall-empty-arguments branch from 8dc2559 to 28d7ca8 Compare July 15, 2026 14:39
@chuenchen309

Copy link
Copy Markdown
Contributor Author

Thanks @bogdankostic — added the release note for the fix and rebased onto latest main, which also dropped a stray release note the branch had picked up from a rebased-over PR. The diff is now just the from_openai_dict_format tool-call fix + its test + release note, and the local suite is green. Ready for another look whenever you have time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

topic:tests type:documentation Improvements on the docs

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants