Skip to content

Python: Surface failed OpenAI Responses as client exceptions - #9925

Draft
Sumedh Aerram (sumedh-aerram) wants to merge 1 commit into
microsoft:mainfrom
sumedh-aerram:fix/python-responses-failure
Draft

Sumedh Aerram (sumedh-aerram) wants to merge 1 commit into
microsoft:mainfrom
sumedh-aerram:fix/python-responses-failure

Conversation

@sumedh-aerram

@sumedh-aerram Sumedh Aerram (sumedh-aerram) commented Nov 1, 2026 •

Copy link
Copy Markdown

Motivation & Context

A failed Responses API generation currently returns an empty normal-looking response and drops the provider error. Applications using exceptions for retries or fallback therefore cannot distinguish the failure from an empty answer.

Description & Review Guide

  • What are the major changes? Route failed response objects and streaming terminal snapshots through the existing ChatClientException path, retaining available provider code/message and exception chaining. Clear failed background-poll continuation tokens before parsing can raise. Add 18 regression cases and document the behavior.
  • What is the impact of these changes? OpenAI Responses clients, including inherited Foundry parsing, surface failed generations consistently for create, structured-output, and resume requests. Successful and incomplete responses keep their existing behavior. Public signatures and serialized formats are unchanged; failed statuses now raise instead of returning empty success.
  • What do you want reviewers to focus on? Failure handling across both response modes, terminal response.created snapshots, and token cleanup before a failed poll raises. Returning only error metadata was rejected because it would continue to bypass exception-based retry/fallback.

Related Issue

Fixes #9921.

The issue has automated reproduction evidence. Explicit maintainer agreement has not yet been recorded; this draft presents the focused fix for confirmation of the failed-response error contract.

AI Assistance

  • No material AI assistance was used.
  • This is an AI-assisted contribution. I reviewed, understood, and verified all submitted content and accept responsibility for it.

AI assistance details: reproduction, implementation, tests, documentation, and PR description.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR links to an agreed issue with no competing open PR, or the Related Issue section documents a trivial-change or repository-automation exception.
  • This is not a breaking change. If it is a breaking change, add the breaking change label (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.

Failed Responses API objects and terminal stream snapshots discarded provider errors and returned empty success. Raise through the existing client exception path and clear failed background resume tokens before parsing.
Copilot AI balanced review requested due to automatic review settings November 1, 2026 02:10
@agent-framework-automation agent-framework-automation Bot added documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python labels Nov 1, 2026
@sumedh-aerram

Sumedh Aerram (sumedh-aerram) commented Nov 1, 2026 •

Copy link
Copy Markdown
Author

Local validation on commit 81e2793f4 (macOS arm64, Python 3.11.17):

  • Regression proof: all 18 new SDK-boundary cases failed before the source fix, then passed.
  • uv run --locked --group tool-runtime poe test -P openai -m "not integration": 775 passed; 94% package line coverage.
  • uv run --locked pytest packages/openai/tests packages/foundry/tests -m "not integration" --import-mode=importlib -o addopts='' -q --tb=short: 1,240 passed.
  • uv run --locked --group tool-runtime poe check-packages: all 86 syntax tasks and 43 source Pyright tasks passed after using the CI setup's optional extras.
  • uv run --locked --group tool-runtime python -m scripts.workspace_poe_tasks ci-test-typing: all 215 package/checker tasks and three sample checkers passed.
  • uv run --locked --group tool-runtime poe check -S: passed.
  • CI pre-commit job, with its official SKIP=poe-check setting: passed. The separate package-quality job above covers that check.
  • Repository markdown code-block check: passed across the complete file set. The interrupted run was resumed from its last file; previously passed, unchanged files were retained.
  • uv build --package agent-framework-openai: wheel and source distribution built successfully.
  • Independent review and re-review found no actionable issues. Six additional partial-tool-call failure exercises raised without local tool execution or follow-up requests.

Full-suite caveat: the first uv run poe test -A run passed 19,873 tests. With all CI optional extras installed, the rerun passed 19,952 tests but had five timing-sensitive failures: telemetry-registry AST parsing and Azure Search GC exceeded their 60-second limits; three shell-policy tests exceeded wall-time bounds. The exact five cases were rerun without changing timeouts: unmodified upstream had one shell-policy timing failure and four passes; this branch passed all five. No unrelated test or source was changed to mask these failures.

Cloud/service integration tests and the Windows/Linux/Python-version matrices were not run locally. Maintainer agreement and any CLA requirement remain separate from automated reproduction.

Upstream fork-workflow runs currently require maintainer approval. Could a maintainer confirm the linked issue direction and approve those runs when appropriate? The CLA check is now successful.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues block the change to surface failed OpenAI responses as exceptions.

No open issues 🎉

What changed in this PR

This PR addresses #9921 by making failed OpenAI Responses raise ChatClientException instead of returning empty, normal-looking results, allowing applications to trigger retries or fallback.

Changes:

  • Surface provider failure details through the existing exception path for non-streaming responses and streaming terminal snapshots.
  • Clear continuation tokens before failed background polls raise.
  • Add 18 regression cases covering create, structured-output, and resume paths, and document the failure contract.
File Description
python/​packages/​openai/​tests/​openai/​test_openai_chat_client.py Adds failure-handling regression cases and updates terminal-status expectations.
python/​packages/​openai/​README.md Documents exceptions, provider error details, and failed-poll token cleanup.
python/​packages/​openai/​AGENTS.md Records failure-handling and continuation-token requirements.
python/​packages/​openai/​agent_framework_openai/​_chat_client.py Adds shared failed-response checks and clears failed-poll tokens before parsing.

Review effort: Balanced

@sumedh-aerram

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

This branch was previously deployed

1 inactive deployment
github-app-auth — 81e2793f Deployed Nov 1, 2026 by sumedh-aerram via add_label #26778
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Python: [Bug]: Failed OpenAI Responses return empty success instead of surfacing provider errors

2 participants