diff --git a/sentry_sdk/ai/utils.py b/sentry_sdk/ai/utils.py index 06c9a23604..9a1853110f 100644 --- a/sentry_sdk/ai/utils.py +++ b/sentry_sdk/ai/utils.py @@ -1,3 +1,4 @@ +import inspect import json from collections import deque from typing import TYPE_CHECKING @@ -38,6 +39,11 @@ def _normalize_data(data, unpack=True): # type: (Any, bool) -> Any # convert pydantic data (e.g. OpenAI v1+) to json compatible format if hasattr(data, "model_dump"): + # Check if it's a class (type) rather than an instance + # Model classes can be passed as arguments (e.g., for schema definitions) + if inspect.isclass(data): + return f"" + try: return _normalize_data(data.model_dump(), unpack=unpack) except Exception as e: diff --git a/tests/utils/test_general.py b/tests/utils/test_general.py index 03182495de..04e82b8c5c 100644 --- a/tests/utils/test_general.py +++ b/tests/utils/test_general.py @@ -2,6 +2,7 @@ import os import pytest +from sentry_sdk.ai.utils import _normalize_data from sentry_sdk.utils import ( @@ -621,3 +622,29 @@ def test_failed_base64_conversion(input): ) def test_strip_string(input, max_length, result): assert strip_string(input, max_length) == result + + +def test_normalize_data_with_pydantic_class(): + """Test that _normalize_data handles Pydantic model classes""" + + class TestClass: + name: str = None + + def __init__(self, name: str): + self.name = name + + def model_dump(self): + return {"name": self.name} + + # Test with class (should NOT call model_dump()) + result = _normalize_data(TestClass) + assert result == "" + + # Test with instance (should call model_dump()) + instance = TestClass(name="test") + result = _normalize_data(instance) + assert result == {"name": "test"} + + # Test with dict containing class + result = _normalize_data({"schema": TestClass, "count": 5}) + assert result == {"schema": "", "count": 5}