From c95d0f19b44c16bd21308a4177d4204510c4fffb Mon Sep 17 00:00:00 2001 From: Muhtasim-Munif-Fahim Date: Mon, 8 Jun 2026 06:32:27 +0600 Subject: [PATCH 1/3] fix: parse realtime error messages --- .../beta/realtime/realtime_response_status.py | 3 ++ .../realtime/realtime_response_status.py | 3 ++ tests/lib/test_realtime_response_status.py | 31 +++++++++++++++++++ 3 files changed, 37 insertions(+) create mode 100644 tests/lib/test_realtime_response_status.py diff --git a/src/openai/types/beta/realtime/realtime_response_status.py b/src/openai/types/beta/realtime/realtime_response_status.py index 7189cd58a1..986da1c8e4 100644 --- a/src/openai/types/beta/realtime/realtime_response_status.py +++ b/src/openai/types/beta/realtime/realtime_response_status.py @@ -12,6 +12,9 @@ class Error(BaseModel): code: Optional[str] = None """Error code, if any.""" + message: Optional[str] = None + """A human-readable description of the error, if any.""" + type: Optional[str] = None """The type of error.""" diff --git a/src/openai/types/realtime/realtime_response_status.py b/src/openai/types/realtime/realtime_response_status.py index 26b272ae5a..967e48886f 100644 --- a/src/openai/types/realtime/realtime_response_status.py +++ b/src/openai/types/realtime/realtime_response_status.py @@ -17,6 +17,9 @@ class Error(BaseModel): code: Optional[str] = None """Error code, if any.""" + message: Optional[str] = None + """A human-readable description of the error, if any.""" + type: Optional[str] = None """The type of error.""" diff --git a/tests/lib/test_realtime_response_status.py b/tests/lib/test_realtime_response_status.py new file mode 100644 index 0000000000..a4c2302f73 --- /dev/null +++ b/tests/lib/test_realtime_response_status.py @@ -0,0 +1,31 @@ +from __future__ import annotations + +from pydantic import BaseModel +import pytest + +from openai.types.beta.realtime import RealtimeResponseStatus as BetaRealtimeResponseStatus +from openai.types.realtime import RealtimeResponseStatus as RealtimeResponseStatus + + +@pytest.mark.parametrize( + "status_cls", + [BetaRealtimeResponseStatus, RealtimeResponseStatus], + ids=["beta", "realtime"], +) +def test_realtime_response_status_error_message(status_cls: type[BaseModel]) -> None: + status = status_cls.model_validate( + { + "error": { + "code": "bad_request", + "message": "The model could not process the request.", + "type": "invalid_request_error", + }, + "type": "failed", + } + ) + + assert status.error is not None + assert status.error.code == "bad_request" + assert status.error.message == "The model could not process the request." + assert status.error.type == "invalid_request_error" + assert status.type == "failed" From 0654a1137cf0bb9fd5493a0af05f8c076778a111 Mon Sep 17 00:00:00 2001 From: Muhtasim-Munif-Fahim Date: Mon, 8 Jun 2026 07:13:04 +0600 Subject: [PATCH 2/3] test: reproduce bare dict construct crash --- tests/test_models.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test_models.py b/tests/test_models.py index cc204bac1d..9f8be87f3b 100644 --- a/tests/test_models.py +++ b/tests/test_models.py @@ -964,6 +964,10 @@ def __getattr__(self, attr: str) -> Item: ... assert model.other == "foo" +def test_bare_dict_annotation() -> None: + assert construct_type(value={"key": "value"}, type_=dict) == {"key": "value"} + + # NOTE: Workaround for Pydantic Iterable behavior. # Iterable fields are replaced with a ValidatorIterator and may be consumed # during serialization, which can cause subsequent dumps to return empty data. From aa646364341d8e2e52890d370ea8f4fcc946cc76 Mon Sep 17 00:00:00 2001 From: Muhtasim-Munif-Fahim Date: Mon, 8 Jun 2026 07:13:16 +0600 Subject: [PATCH 3/3] fix: handle bare dict annotations in construct_type --- src/openai/_models.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/openai/_models.py b/src/openai/_models.py index ed4c1f82d6..664405ab41 100644 --- a/src/openai/_models.py +++ b/src/openai/_models.py @@ -657,7 +657,10 @@ def construct_type(*, value: object, type_: object, metadata: Optional[List[Any] if not is_mapping(value): return value - _, items_type = get_args(type_) # Dict[_, items_type] + args = get_args(type_) + if len(args) < 2: + return value + items_type = args[1] return {key: construct_type(value=item, type_=items_type) for key, item in value.items()} if (