Client or integration
Other
Area
Authentication and account pool
Summary
The generic-OAuth 429 ladder reserves a hop from the shared request budget, and the reservation is the charge (src/server/responses/adapter-dispatch.ts:719). The same budget is then handed to the adapter for the replay (:420), and an adapter that reserves for itself charges again — Kiro reserves immediately before its physical send at src/adapters/kiro-retry.ts:171. The non-adapter transient helper has the same shape: the hop is not supplied through pendingHopPermit, so its onSendsConsumed reporter adds a second charge.
One physical replay can therefore be counted twice, or refused as a second target transition. The passthrough ladder already solves this by reserving with countedExternally: true and handing the permit down through pendingHopPermit (src/server/responses/passthrough-dispatch.ts:1115).
This predates 2.56.0 and was found while fixing a related permit leak in that release; it is the remaining half of the same accounting story.
Reproduction
- Configure a generic-OAuth provider with two or more accounts and an adapter that reserves its own sends (Kiro), or any provider with a transient retry policy.
- Make the first send return 429 so the roster rotates.
- Watch the request's send accounting: the single replay is charged by the hop reservation and again by the adapter or by
onSendsConsumed.
Suggested fix: mirror the passthrough shape — reserve the hop with countedExternally: true and pass it through pendingHopPermit so the layer that actually dispatches settles it.
Version
2.56.0 (e4a8539)
Operating system
macOS 15.5
Provider and model
kiro / any generic-OAuth provider with two or more accounts
Logs or error output
(accounting defect; visible as an early request_send_budget refusal or a doubled send count)
Checks
Client or integration
Other
Area
Authentication and account pool
Summary
The generic-OAuth 429 ladder reserves a hop from the shared request budget, and the reservation is the charge (
src/server/responses/adapter-dispatch.ts:719). The same budget is then handed to the adapter for the replay (:420), and an adapter that reserves for itself charges again — Kiro reserves immediately before its physical send atsrc/adapters/kiro-retry.ts:171. The non-adapter transient helper has the same shape: the hop is not supplied throughpendingHopPermit, so itsonSendsConsumedreporter adds a second charge.One physical replay can therefore be counted twice, or refused as a second target transition. The passthrough ladder already solves this by reserving with
countedExternally: trueand handing the permit down throughpendingHopPermit(src/server/responses/passthrough-dispatch.ts:1115).This predates 2.56.0 and was found while fixing a related permit leak in that release; it is the remaining half of the same accounting story.
Reproduction
onSendsConsumed.Suggested fix: mirror the passthrough shape — reserve the hop with
countedExternally: trueand pass it throughpendingHopPermitso the layer that actually dispatches settles it.Version
2.56.0 (e4a8539)
Operating system
macOS 15.5
Provider and model
kiro / any generic-OAuth provider with two or more accounts
Logs or error output
(accounting defect; visible as an early request_send_budget refusal or a doubled send count)Checks