Repository navigation
Classify throttling 403 responses as upstream_http_error - #2435
Open
Tyagiquamar wants to merge 1 commit into
Open
Tyagiquamar wants to merge 1 commit into
Tyagiquamar wants to merge 1 commit into
Conversation
A 403 that names a rate limit is a quota signal, not a credential failure. The 401/403 branch turned it into connection_rejected, which tells the agent to re-authenticate and drops the upstream reason (Gmail falls over on a burst of parallel users.messages.get calls, UsefulSoftwareCo#2420). Detect throttling structurally: Retry-After or x-ratelimit-remaining: 0, or an exact rateLimitExceeded / RESOURCE_EXHAUSTED / too_many_requests value in an error, reason, status, or code field. Throttling 403s now fall through to the ordinary upstream_http_error path and keep the upstream message; permission 403s still get connection_rejected, and scope shortfalls still get oauth_scope_insufficient.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A 403 that means "you are going too fast" is now reported as
upstream_http_errorwith the upstream message intact, instead ofconnection_rejectedwith a re-authenticate prompt.Root cause
In
packages/plugins/openapi/src/sdk/backing.ts, every non-2xx 401/403 enters the credential branch and becomesconnection_rejectedunless it names a scope shortfall. Google reports per-user quotas as HTTP 403 (rateLimitExceeded,RESOURCE_EXHAUSTED), and GitHub's secondary rate limit is also a 403 withRetry-After, so a burst of Gmailusers.messages.getcalls told the agent its credentials were bad. Re-authenticating cannot clear a quota, and the upstream reason was replaced with re-auth guidance.Technical solution
detectRateLimitedchecks two structural signals:Retry-After, orx-ratelimit-remaining: 0;rateLimitExceeded,userRateLimitExceeded,rate_limit_exceeded,RESOURCE_EXHAUSTED,too_many_requests) in anerror,reason,status, orcodefield at any depth (bounded at 6 levels).upstream_http_errorpath, so the upstream message and status survive.connection_rejected, and scope shortfalls still getoauth_scope_insufficientbecause that branch only runs when the response is not throttling.Tests
Added to
packages/plugins/openapi/src/sdk/upstream-failures.test.ts:rate-limit 403 (Google RESOURCE_EXHAUSTED) is upstream_http_error: Google's nestederror.errors[].reason: rateLimitExceededbody now yieldsupstream_http_error, status 403, message "Rate Limit Exceeded".throttling 403 with Retry-After is upstream_http_error: GitHub's secondary-rate-limit body withRetry-After: 60yieldsupstream_http_errorand keeps the message.ordinary 403 without a scope signal stays connection_rejectedand both scope-insufficient 403 tests still pass.Commands run in
packages/plugins/openapi:bun run test -- src/sdk/upstream-failures.test.ts(18 passed)bun run test -- src/sdk/upstream-failures.test.ts -t "403"(6 passed, includes the false-positive guard)bun run typecheck(clean)bunx oxlint -c .oxlintrc.jsonc <changed files> --deny-warnings(0 warnings, 0 errors)bunx oxfmt --check <changed files>(clean)Note: the
Format,Lint,Typecheck,Test, andChanged pathsjobs inci.ymlare gated to same-repo branches, so they reportskippingon a fork PR. The local runs above are the equivalent evidence.Changeset added at
.changeset/throttling-403-classification.md(patch,@executor-js/plugin-openapi).Fixes #2420