Skip to content

provider-retry never retries Account Pooler 429/502 failures #4839

Closed

Description

@matthiasvongrundherr

Summary

When a turn fails because the Account Pooler returned 429 (no eligible account) or 502 (could not reach the upstream), provider-retry declines to retry it. The thread stays in error until someone sends a new message, even after the pooler has recovered.

Versions and environment

  • bb 0.44.0 and 0.45.0 (desktop app), macOS
  • Claude Code and Codex threads routed through the Account Pooler
  • provider-retry 0.1.0 (builtin), default settings

Steps to reproduce

  1. Run a Claude Code or Codex thread through the Account Pooler.
  2. During a turn, the pooler answers 429 (no eligible account) or 502 (upstream unreachable).
  3. The turn fails and the thread stays in error; no retry is queued.
    Observed in production, not reproduced on demand.

Expected vs actual

Actual:
- Claude Code: API Error: Request rejected (429) · No Account Pooler account is currently eligible. is classified rate-limit, but no rate-limit state is recorded for the thread, so the retry decision ends in no-rate-limit-state. The pooler's own 429 carries a retry-after with the earliest reset; nothing reads it.
- Codex: exceeded retry limit, last status: 429 Too Many Requests is classified too-many-failed-attempts and treated as not retryable.
- Account Pooler could not reach Anthropic. / Account Pooler could not reach ChatGPT. (502) ends as internal (Claude Code) or stream-disconnected (Codex), also not retryable.

Expected:
Failures the Account Pooler itself marks as temporary are retried by provider-retry: a pool 429 at the pooler's retry-after (within maximumWait), a pool 502/503 with the existing backoff. An invalid pooler bearer token (401) stays non-retryable.

Evidence

Impact in our workspace (Sept 20 to Oct 3): one 429 wave stopped seven threads at the same moment for 1 h 50 min; another left eight Codex threads idle for almost 10 h overnight; a roughly 30-minute 502 outage left a thread idle for 5 h 15 min. A manual resume after recovery (a new message or bb thread retry) worked every time.

provider-retry was disabled on this machine during these incidents (it is enabled now). The decline reasons above come from decideRetry in the 0.45.0 bundle applied to the errorInfo recorded for these failures.

Related: #4166 and #4332 (automations after transient provider failures), #4131 (provider-retry scope).

I can put up a PR with a regression test if this direction works for you.

What you ruled out

No response

Suggested priority and effort (optional)

No response

Checks

  • I reproduced this on the latest release or on main, or I say above that I could not.
  • I searched open and closed issues for the same problem.
  • If an agent wrote this, the body ends with > AGENT GENERATED and links the thread or report.

AGENT GENERATED. The underlying incident report is internal and not linkable.

Activity

  1. added theissue type on Oct 4, 2026
  2. added
    providersCross-provider bridges, models, login
    provider-retryBuilt-in plugin: provider-retry
    confirmed-reproBug reproduced again from a clean trusted checkout; see linked report
    on Oct 4, 2026
  3. bb-slop-cop commented on Oct 4, 2026

    @bb-slop-cop
    Contributor

    🚨 SLOP COP 🚨 · new-issue-autopilot

    • Classification: Bug · Priority High · Effort Medium; labels providers, provider-retry.
    • Report: Reproduction and root-cause report — REPRODUCED, high confidence; confirmed-repro.
    • Evidence: On trusted main 4d15c1da0, both clean-checkout runs show five missing retry requests; the HTTP 401 and overload controls pass. Existing retry tests (15) and targeted pool tests (3) pass. This verifies enabled-plugin scheduling, not the reported live outages.
    • Root cause: The policy accepts only overloads or resettable subscription limits. These gateway failure classifications are declined, and the failure payload does not carry the pool's Retry-After deadline.
    • No PR: A safe, deadline-aware fix needs cross-subsystem retry metadata or a product-policy decision, outside this rule's simple-fix limits.

    AGENT GENERATED

  4. brsbl commented on Oct 4, 2026

    @brsbl
    Collaborator

    Adding the requested user behavior for the all-accounts-exhausted case: keep the message queued and automatically retry when the first pooled account becomes usable, using the reset information already shown in Account Pooler settings. Users should not have to watch the settings page and manually resend after quota recovers.

    Acceptance criteria:

    • When every eligible account for the requested provider/model is rate-limited, preserve the pending message/turn and show that it is waiting, with its scheduled retry time.
    • Schedule against the earliest account recovery time. If one account has multiple blocking windows, use the time when all of its relevant windows have cleared, then choose the earliest such time across accounts.
    • Resume automatically through normal pool selection after that deadline, without requiring a new user message or duplicating the pending request. For example, accounts recovering in 20 and 50 minutes should resume work at the 20-minute recovery (plus the existing reset buffer/jitter).
    • Integrate with the existing automatic-retry settings and cancellation behavior. Do not treat disabled accounts, invalid credentials, or limits without a known reset as known scheduled recoveries.

    Source review at 75308f407660efe0f93ffb9626936e5067b5bb03 confirms that the pool already calculates the earliest recovery deadline and returns it in retry-after. The settings UI uses the same blocking-reset calculation.

    The comparison with direct requests is supported by the existing provider-retry policy: it schedules resettable subscription-limit failures when structured limit state is available and the reset is within the configured maximum wait. The failed-turn handler queues that retry. That behavior should also work when the reset information comes from the pool.

    This follow-up is a user requirement plus source inspection, not a new live reproduction. No accounts or routing settings were changed, and no local tests were run. CLI version: 0.45.1-nightly.37130000802.1. Originating bb thread: thr_zwnrc88xqv.

    AGENT GENERATED

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    confirmed-reproBug reproduced again from a clean trusted checkout; see linked reportprovider-retryBuilt-in plugin: provider-retryprovidersCross-provider bridges, models, login

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions