Skip to content

fix(types): preserve realtime error messages - #3906

Open
nanookclaw wants to merge 1 commit into
openai:mainfrom
nanookclaw:fix/realtime-error-message
Open

nanookclaw wants to merge 1 commit into
openai:mainfrom
nanookclaw:fix/realtime-error-message

Conversation

@nanookclaw

Copy link
Copy Markdown

Fixes #2502

The Realtime API can return a human-readable status_details.error.message, but both stable and beta RealtimeResponseStatus.Error models currently drop it during validation.

This change:

  • adds the optional message field to both generated model variants;
  • updates both corresponding entries in api_reference/openapi.transformed.yml;
  • adds regression coverage for preserving a supplied message and accepting an omitted one.

The change is limited to the generated schema/model surface and does not alter request or response handling.

Validation:

  • PYTEST_DISABLE_PLUGIN_AUTOLOAD=1 uvx --from uv==0.12.1 uv run --locked --all-extras python -m pytest -p pytest_asyncio.plugin -o addopts= tests/test_realtime_response_status.py -q — 2 passed
  • ruff check on changed Python files — passed
  • ruff format --check on changed Python files — passed
  • python3 -m py_compile on changed Python/test files — passed
  • OpenAPI YAML parse — passed
  • git diff --check — passed

@nanookclaw
nanookclaw requested a review from a team as a code owner September 19, 2026 05:12
@jnohclee-rgb

Copy link
Copy Markdown

AI-assisted offline comparison of head c23fa124a154463552d3e1657b9fc0a9affaa0ac and its parent 618bb312e52c2b62f75f56602b7388e6d023aa33, with Python 3.14.7 / Pydantic 2.13.5. I exercised both stable and beta status models through parse_obj and SDK construct, using supplied text, omitted message, explicit null, and an intentionally invalid object (16 cases per source revision).

One useful distinction for the description/tests: in this environment the parent already preserves a supplied message as an allowed extra field, through both paths. The current preservation assertion also succeeds against the parent. The PR makes message an explicitly declared optional field, adds the omitted-value default, and changes validation semantics:

Case (both model variants) Parent PR head
supplied text, parse or construct attribute and model_dump preserve text same
omitted message, parse or construct attribute absent; key absent in model_dump attribute None; key present with None in default model_dump
explicit null, parse or construct preserved preserved
object value, parse_obj accepted as extra ValidationError
object value, construct preserved as extra preserved through SDK's permissive construction

A small discriminator for the typed-model fix would be asserting that message is declared in the error model's fields (and/or explicitly checking the omitted default). The description could distinguish missing typed/schema coverage from dropped runtime data. I cannot establish the original issue's runtime/version from these results.

Minimal parent-preservation check:

status = parse_obj(RealtimeResponseStatus, {"error": {"message": "fictional error"}})
assert status.error.message == "fictional error"
assert status.model_dump()["error"]["message"] == "fictional error"

All inputs were fictional and execution was network-denied. This is a pinned model-level comparison on Pydantic v2, not a live WebSocket test, a Pydantic v1 result, or full-suite coverage.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Realtime API Pydantic Models incomplete for RealtimeResponseStatus type

2 participants