ref(google-genai): Remove set_data_normalized for the gen_ai.response.finish_reasons attribute#5506
Conversation
…ish_reasons attribute
gen_ai.response.finish_reasons attributeset_data_normalized for gen_ai.response.finish_reasons attribute
set_data_normalized for gen_ai.response.finish_reasons attributeset_data_normalized for the gen_ai.response.finish_reasons attribute
Semver Impact of This PR🟢 Patch (bug fixes) 📋 Changelog PreviewThis is how your changes will appear in the changelog. Bug Fixes 🐛Openai
Other
Documentation 📚
Internal Changes 🔧
🤖 This preview updates automatically when you update the PR. |
| span.set_data( | ||
| SPANDATA.GEN_AI_RESPONSE_FINISH_REASONS, json.dumps(finish_reasons) | ||
| ) |
There was a problem hiding this comment.
Bug: Using json.dumps instead of set_data_normalized incorrectly serializes single-element finish_reasons lists, creating an inconsistency with the streaming path.
Severity: MEDIUM
Suggested Fix
Revert to using set_data_normalized(span, SPANDATA.GEN_AI_RESPONSE_FINISH_REASONS, finish_reasons). This function correctly handles both single-element lists by unpacking them and multi-element lists by JSON-serializing them, maintaining consistency with the streaming code path.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent.
Verify if this is a real issue. If it is, propose a fix; if not, explain why it's not
valid.
Location: sentry_sdk/integrations/google_genai/utils.py#L884-L886
Potential issue: The switch from `set_data_normalized` to `json.dumps` for setting the
`finish_reasons` data on a span introduces a data format inconsistency. The
`set_data_normalized` function unpacks single-element lists, meaning a list like
`["STOP"]` becomes the plain string `"STOP"`. The new implementation using `json.dumps`
will serialize it as the string `'["STOP"]'`. This creates a discrepancy with the
streaming implementation, which still uses `set_data_normalized` and produces a plain
string for a single finish reason. This change will break consumers of the span data
that expect a plain string for a single reason in non-streaming scenarios.
Did we get this right? 👍 / 👎 to inform future reviews.
There was a problem hiding this comment.
The aim is to have a consistent type for an attribute, so if lists are possible they should always be lists.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
| set_data_normalized( | ||
| span, SPANDATA.GEN_AI_RESPONSE_FINISH_REASONS, finish_reasons | ||
| span.set_data( | ||
| SPANDATA.GEN_AI_RESPONSE_FINISH_REASONS, json.dumps(finish_reasons) |
There was a problem hiding this comment.
Inconsistent finish_reasons format between streaming and non-streaming
High Severity
The change creates inconsistent serialization for gen_ai.response.finish_reasons between streaming and non-streaming paths. Non-streaming now always stores as JSON array (e.g., '["STOP"]'), while streaming still uses set_data_normalized which unpacks single-element lists to plain strings (e.g., "STOP"). OpenTelemetry specifies this attribute as string[] type, requiring consistent array format. Consumers parsing this attribute will encounter different formats depending on whether streaming was used, breaking data consistency.
There was a problem hiding this comment.
The aim is to have a consistent type for an attribute, so if lists are possible they should always be lists.


Description
Remove
set_data_normalized()for attributes that do not require normalization.Since
extract_finish_reasons(response)returns a list of strings, we can directly serialize to JSON.This attribute does not adhere to our conventions as the conventions indicate type it be a string: https://github.com/getsentry/sentry-conventions/blob/0e79c16961a747152afc2c8d86311351d2c05554/model/attributes/gen_ai/gen_ai__response__finish_reasons.json#L4
Issues
Reminders
tox -e linters.feat:,fix:,ref:,meta:)