fix(events): make state serialization fallback resilient per value - #6932
Open
ALDRIN121 wants to merge 1 commit into
Open
fix(events): make state serialization fallback resilient per value#6932ALDRIN121 wants to merge 1 commit into
ALDRIN121 wants to merge 1 commit into
Conversation
The _make_json_serializable fallback delegated wholesale to pydantic_core.to_jsonable_python, which raises on deferred Pydantic models (e.g. GroundingMetadata with MockValSer under google-genai 2.18+) before serialize_unknown can apply, aborting event serialization and the enclosing invocation. Walk the structure and convert each leaf under try/except, falling back to repr with a warning naming the affected paths, so the fallback can never raise. Fixes google#6848
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.
Please ensure you have read the contribution guide before creating a pull request.
Link to Issue or Description of Change
1. Link to an existing issue (if applicable):
GoogleSearchAgentToolparallel responses fail to serialize deferredGroundingMetadata(MockValSer) #6848This is the complementary defense-in-depth fix discussed in the #6848 thread
(agreed with @andrewrfitz and acknowledged by @llalitkumarrr): #6849 fixes the
root cause by force-building deferred Pydantic serializers; this PR makes the
serialization fallback itself resilient so a deferred model can never kill the
invocation, even if it reaches serialization.
Problem:
When
google-genai>= 2.18 leaves aMockValSerplaceholder on aGroundingMetadataproduced via nested validation (defer_build=True),serializing that value with
to_jsonable_python(value, serialize_unknown=True)raises
TypeErrorbeforeserialize_unknowncan apply. The wholestate_delta/agent_statefallback then crashes, abortingmerge_parallel_function_response_eventswhen a search tool runs in parallelwith another tool.
Solution:
Rewrite
_make_json_serializableto walk dicts/lists recursively and converteach leaf individually under
try/except, replacing only the raising valueswith their
reprand logging a warning that names the affected paths. Healthyinput produces output byte-identical to
to_jsonable_python(enforced by aparity test), so the existing serializers that honor callers'
exclude/includedirectives are unaffected. Container subclasses with brokeniteration also fall back to
reprinstead of escaping.Testing Plan
Unit Tests:
pytest tests/unittests/events/test_event_actions.pypytest ./tests/unitteststox(py3.10–3.14)test_import_loadingbaseline noted in #6849) — identical with and without this change; all 26 pass standalone.pre-commit run --files(both changed files)New tests reproduce the exact failure shape from the issue — a Pydantic model
whose
__pydantic_serializer__is a placeholder (_DeferredModelwith__pydantic_serializer__ = object()) — at the root, in dicts, nested incontainers, and inside
state_delta/agent_stateviamodel_dump(mode='json').Manual End-to-End (E2E) Tests:
The issue reproduces without a model call or API key, and the deferred-model
unit tests exercise the same serialization path (
EventActions.model_dump→ wrap serializer → fallback) that crashes in
merge_parallel_function_response_events. No E2E setup beyond the unit suiteis needed for this change; the root-cause behavior is additionally covered by
#6849.
Checklist
Additional context
main; change is one commit, two files.adk-docsPR needed).