Skip to content

fix: handle raw dict output_schema in SetModelResponseTool#5470

Closed
harche wants to merge 2 commits intogoogle:mainfrom
harche:fix/dict-output-schema-crash
Closed

fix: handle raw dict output_schema in SetModelResponseTool#5470
harche wants to merge 2 commits intogoogle:mainfrom
harche:fix/dict-output-schema-crash

Conversation

@harche
Copy link
Copy Markdown

@harche harche commented Apr 24, 2026

Summary

  • Fix TypeError: unhashable type: 'dict' when passing a raw dict instance as output_schema to LlmAgent
  • Add test for the raw dict schema case

Fixes #5469

Root Cause

SetModelResponseTool.__init__ sets annotation=output_schema (the dict instance) as a function parameter annotation. Downstream, _is_builtin_primitive_or_compound does annotation in _py_builtin_type_to_schema_type.keys(), which tries to hash the dict instance and raises TypeError.

Fix

Add an isinstance(output_schema, dict) branch that uses dict (the type, which is hashable and already in _py_builtin_type_to_schema_type) as the annotation instead of the dict instance.

Test plan

  • Added test_tool_initialization_raw_dict_instance covering the exact crash case
  • Existing test_tool_initialization_dict_schema (uses dict[str, int] GenericAlias) still passes — no regression

@google-cla
Copy link
Copy Markdown

google-cla Bot commented Apr 24, 2026

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@adk-bot adk-bot added the tools [Component] This issue is related to tools label Apr 24, 2026
@adk-bot
Copy link
Copy Markdown
Collaborator

adk-bot commented Apr 24, 2026

Response from ADK Triaging Agent

Hello @harche, thank you for creating this PR!

Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). You can visit https://cla.developers.google.com/ to see your current agreements or to sign a new one.

This information will help reviewers to review your PR more efficiently. Thanks!

When output_schema is a raw dict instance (e.g.,
{"type": "object", "properties": {...}}), SetModelResponseTool sets it
as the parameter annotation directly. This crashes in
_is_builtin_primitive_or_compound because dict instances are not
hashable and the check does `annotation in dict.keys()`.

Fix: add an explicit isinstance(output_schema, dict) branch that uses
`dict` (the type) as the annotation instead of the dict instance.

Fixes google#5469
@harche harche force-pushed the fix/dict-output-schema-crash branch from 6b9b9ef to 6e44f37 Compare April 24, 2026 11:44
@rohityan rohityan self-assigned this Apr 24, 2026
@harche
Copy link
Copy Markdown
Author

harche commented Apr 26, 2026

After testing this more, the annotation=dict fix stops the crash but silently drops schema enforcement. The set_model_response tool declaration ends up as:

parameters=Schema(
  properties={'response': Schema(type=OBJECT)},
  required=['response'],
  type=OBJECT
)

The model sees "return any dict" with no field constraints — it ignores field names, types, required properties, and enum values from the original schema. In our evals the model returned completely different JSON structures that didn't match the schema at all.

The deeper issue is that SetModelResponseTool can't faithfully represent arbitrary JSON schemas as function parameter annotations. A better fix would be to extend can_use_output_schema_with_tools() to return True for all Gemini models (not just Vertex AI), so the native response_schema path is used instead of the tool-based workaround.

Closing this in favor of updating the issue with the full findings.

@harche harche closed this Apr 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

tools [Component] This issue is related to tools

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SetModelResponseTool crashes with TypeError when output_schema is a raw dict

4 participants