Skip to content

fix(providers): preserve rejection status in failed Responses - #405

Closed
jcs130 wants to merge 1 commit into
Pal-AI-Lab:mainfrom
jcs130:fix/responses-rejection-status-20261111
Closed

jcs130 wants to merge 1 commit into
Pal-AI-Lab:mainfrom
jcs130:fix/responses-rejection-status-20261111

Conversation

@jcs130

@jcs130 jcs130 commented Nov 11, 2026

Copy link
Copy Markdown

A Responses request can return HTTP 200 and then report an explicit upstream 400 rejection in its failed terminal event. The transport currently exposes that as status 0, causing MainLoop to submit the rejected request three times in the same batch.

Preserve structured upstream error statuses and known rejection codes, including compatible gateway status prefixes. ProviderAttempt keeps the actual HTTP status, and the original error body, partial output and usage remain available. Unknown failures keep status 0.

Validation: 5,209 tests passed, 4 skipped; typecheck passed. A transport-to-MainLoop integration fixture reproduces three requests before the fix and one afterward. Both streaming and unary failed Responses are covered.

Failed Responses carried HTTP 200 and were reduced to status 0, so MainLoop resubmitted explicit 400 rejections three times per batch. Preserve the embedded rejection status while retaining actual attempt HTTP status, partial output and usage. Transport and MainLoop integration tests verify one request per rejected batch.
@Phantivia

Copy link
Copy Markdown
Member

Thanks @jcs130 for tracing this through the transport and the main loop, and for the integration fixture.

We are not taking this change. src/providers/transport/ is shared by every upstream, and we do not want it to decide a status from one upstream's error wording. The <400> message prefix and the DataInspectionFailed codes follow one provider's format, and a status read out of error text would then decide whether the main loop resubmits.

The repeated requests come from two retry layers multiplying. The transport re-sends a failed response up to three more times (the [1000, 4000, 10000] delays in src/providers/transport/response-http.ts), and the main loop resubmits a status-0 failure up to twice (DEFAULT_RESUBMIT in src/core/loop.ts), so one rejected request can go out up to 12 times. #385 deals with this in the transport: once a terminal failed response is returned after one attempt, the same request goes out at most 3 times.

#385 is still waiting on the question from Nov 9: which upstream returns response.failed there, and the error object from one such response.

Closing this PR.

@Phantivia Phantivia closed this Nov 12, 2026
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.

2 participants