fix: repair malformed JSON in streaming tool call arguments - #54
Merged
mateo-di merged 2 commits intoDec 11, 2025
Merged
Conversation
Fixes intermittent JSON parse errors in Responses API streaming with
tool calls when using Gemini models. The error manifests as:
"Unexpected non-whitespace character after JSON at position X"
Root cause: Gemini streaming can send duplicate/overlapping JSON chunks
that when naively joined with "".join() produce malformed JSON like:
'{"address":"School"}{"address":"School"}'
Solution: Use Python's built-in JSONDecoder.raw_decode() to extract
the first valid JSON object. This is the canonical, C-optimized O(n)
solution for handling "extraneous data at the end" of JSON strings.
Changes:
- Add _validate_and_repair_tool_arguments() using raw_decode()
- Apply fix to get_combined_tool_content() and get_combined_function_call_content()
- Add 19 comprehensive unit tests covering valid, malformed, edge cases
Shortcut: sc-522840
mateo-di
force-pushed
the
bug/sc-522840/intermittent-json-parse-errors-in-responses
branch
from
December 5, 2025 17:41
d4d204c to
4306a4b
Compare
…errors-in-responses
mateo-di
marked this pull request as ready for review
December 11, 2025 18:58
3 tasks
Cartofante
pushed a commit
that referenced
this pull request
Feb 4, 2026
Features restored: - [PR #70] Azure URL suffix stripping - Strip operation suffixes (/chat/completions, /embeddings, etc.) from deployment URLs to prevent 404 errors when Azure SDK appends them again - [PR #54] JSON repair for streaming tool calls - Use JSONDecoder.raw_decode() to handle malformed JSON from Gemini streaming that sends duplicate/overlapping chunks Integration approach: - PR #70: Restored regex-based stripping in select_azure_base_url_or_endpoint() with docstring explaining the fix. Added 12 unit tests. - PR #54: Restored _validate_and_repair_tool_arguments() function and integrated it into get_combined_tool_content() and get_combined_function_call_content(). Added 19 unit tests. Verified: syntax checks, ruff linting passed Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
mateo-di
added a commit
that referenced
this pull request
Feb 10, 2026
Static registry of critical CARTO customizations that must survive upstream syncs. The resolver should verify all patterns exist after every sync to prevent silent feature regressions (like the OCI Gemini and Snowflake tool calling drops in v1.81.0). Tracks: OCI Gemini (#68), Snowflake streaming/tool calling (#38, #58), Azure URL stripping (#70), JSON repair (#54), Redis sessions (#16).
3 tasks
3 tasks
This was referenced Apr 10, 2026
3 tasks
3 tasks
3 tasks
3 tasks
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.
Description
Shortcut
Fixes intermittent JSON parse errors in Responses API streaming with tool calls when using Gemini models.
Problem
The error manifests as:
Root cause: Gemini streaming can send duplicate/overlapping JSON chunks that when naively joined with
"".join()produce malformed JSON like:Solution
Use Python's built-in
JSONDecoder.raw_decode()to extract the first valid JSON object. This is the canonical, C-optimized O(n) solution for handling "extraneous data at the end" of JSON strings.Reference: Python JSON Documentation
Changes
_validate_and_repair_tool_arguments()function usingraw_decode()get_combined_tool_content()andget_combined_function_call_content()Type of change
Acceptance
pytest tests/test_litellm/litellm_core_utils/test_streaming_chunk_builder_utils.py -vBasic checklist