Skip to content

fix(openai): Tool name or arguments might be empty/null#9828

Closed
tcx4c70 wants to merge 1 commit into
pgadmin-org:masterfrom
tcx4c70:fix/openai/empty-tool-name-or-arg
Closed

fix(openai): Tool name or arguments might be empty/null#9828
tcx4c70 wants to merge 1 commit into
pgadmin-org:masterfrom
tcx4c70:fix/openai/empty-tool-name-or-arg

Conversation

@tcx4c70

@tcx4c70 tcx4c70 commented Apr 7, 2026

Copy link
Copy Markdown
Contributor

Some providers might return empty/null values in streaming delta (I guess it's to keep schema consistent?). For example, streaming data for a request might be:

data: { ... "choices":[{"index":0,"delta":{"role":"assistant","tool_calls":[{"index":0, ... "function":{"name":"get_database_schema","arguments":""}}]}}] ... }
data: { ... "choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"name":null,"arguments":"{}"}}]}}] ... }
data: { ... "choices":[{"index":0,"finish_reason":"tool_calls","delta":{}}] ... }
data: [DONE]

Then pgAdmin will combine the delta to a tool call with name "null" and arguments "{}", which leads to a error that can't find the tool.

Though I don't find the official doc that mentions we should skip null value in delta, the official openai python sdk skips null values [1].

This commit is to skip null values in streaming delta to avoid empty/null tool name or arguments.

[1] https://github.com/openai/openai-python/blob/58184ad545ee2abd98e171ee09766f259d7f38cd/src/openai/lib/streaming/_deltas.py#L6

Summary by CodeRabbit

  • Bug Fixes
    • Fixed an issue where empty values were incorrectly overwriting valid tool call information when streaming responses from OpenAI, improving the reliability of tool call handling.

Some providers might return empty/null values in streaming delta (I
guess it's to keep schema consistent?). For example, streaming data for
a request might be:

data: { ... "choices":[{"index":0,"delta":{"role":"assistant","tool_calls":[{"index":0, ... "function":{"name":"get_database_schema","arguments":""}}]}}] ... }
data: { ... "choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"name":null,"arguments":"{}"}}]}}] ... }
data: { ... "choices":[{"index":0,"finish_reason":"tool_calls","delta":{}}] ... }
data: [DONE]

Then pgAdmin will combine the delta to a tool call with name "null" and
arguments "{}", which leads to a error that can't find the tool.

Though I don't find the official doc that mentions we should skip null
value in delta, the official openai python sdk skips null values [1].

This commit is to skip null values in streaming delta to avoid
empty/null tool name or arguments.

[1] https://github.com/openai/openai-python/blob/58184ad545ee2abd98e171ee09766f259d7f38cd/src/openai/lib/streaming/_deltas.py#L6

Signed-off-by: Adam Tao <tcx4c70@gmail.com>
@coderabbitai

coderabbitai Bot commented Apr 7, 2026

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7298c6e9-e62b-49c7-adeb-a2cd98b08d62

📥 Commits

Reviewing files that changed from the base of the PR and between d59fcf3 and 65cc8b2.

📒 Files selected for processing (1)
  • web/pgadmin/llm/providers/openai.py

📝 Walkthrough

Walkthrough

The change adds truthiness checks to tool call field assignments in OpenAI's SSE stream parsing to prevent empty-string overwrites and concatenations while processing tool call deltas.

Changes

Cohort / File(s) Summary
OpenAI Stream Parser
web/pgadmin/llm/providers/openai.py
Added conditional checks in _read_openai_stream to only update tool call name field and append to arguments field when their corresponding values are truthy, preventing empty-string overwrites during delta accumulation.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰 A nimble fix for streaming flows,
Where empty strings no longer creep,
Tool calls now safely grow and grow,
With truthiness to guard so deep!
Two lines to keep the deltas sweet

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and specifically describes the main change: handling empty/null values in OpenAI tool name or arguments fields to prevent errors.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

dpage pushed a commit that referenced this pull request Jun 9, 2026
…#9828)

Some OpenAI-compatible providers emit empty or null name/arguments/id
fields in streaming continuation deltas to keep the response schema
stable. pgAdmin's accumulator overwrote the real tool name (captured in
the first delta) with the later null, producing a tool call named "null"
that could not be dispatched.

Skip falsy name/arguments/id when accumulating (matching the OpenAI
Python SDK, which ignores nulls the same way) so the values captured in
the first delta survive. Also guard against a null `function` object in
a delta, which previously raised TypeError. Without the id guard a null
id in a continuation delta clobbered the real id, which the final build
then replaced with a random uuid rather than the provider's id.

Adds a unit test covering the null-continuation, multi-chunk-arguments,
and null-function cases, and a 9.16 release note.
@dpage

dpage commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Merged to master as 0223e8a (squashed, with you as author). Thanks @tcx4c70 — nice catch, and the OpenAI SDK reference was helpful.

Folded in two related fixes while merging, since they're the same root cause (providers emitting null fields in continuation deltas):

  • Applied the same falsy-guard to the tool-call id — a null id in a later delta was clobbering the real id captured in the first delta, which the final build then replaced with a random uuid instead of the provider's id.
  • Guarded against a null function object in a delta, which would otherwise raise TypeError.

Also added a unit test (web/pgadmin/llm/tests/test_openai_stream.py) covering the null-continuation, multi-chunk-arguments, and null-function cases, plus a 9.16 release note.

@dpage dpage closed this Jun 9, 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