Skip to content

Auth profile fallback doesn't trigger on OAuth 403 permission_error (expired plan) #31306

@Kenneth77chu

Description

@Kenneth77chu

Problem

When an OAuth auth profile (anthropic:200) returns HTTP 403 with permission_error: OAuth authentication is currently not allowed for this organization (due to expired plan), the Gateway does not fall back to the next available profile (anthropic:100). Instead, it keeps retrying the failed profile indefinitely.

Expected Behavior

403 permission_error should be classified as auth_permanent (or similar), triggering automatic rotation to the next healthy profile — same as how billing or rate_limit errors trigger fallback.

Actual Behavior

  • Gateway keeps selecting the expired OAuth profile because lastGood still points to it
  • No cooldown or disabled state is applied to the failing profile
  • The agent becomes unresponsive until a human manually switches the model/profile
  • In our case, 20+ consecutive 403 errors over ~30 minutes before manual intervention

Reproduction

  1. Set up two auth profiles: anthropic:100 (token, valid) and anthropic:200 (OAuth, expired plan)
  2. Let lastGood.anthropic point to anthropic:200
  3. Send a message — Gateway tries :200, gets 403, but does not rotate to :100

Environment

  • OpenClaw version: 2026.2.26 (bc50708)
  • OS: macOS (arm64)
  • Node: v22.22.0

Logs

2026-03-02T03:56:42.424Z [agent/embedded] embedded run agent end: isError=true error=HTTP 403 permission_error: OAuth authentication is currently not allowed for this organization.

(Repeated 20+ times without fallback)

Suggested Fix

Map 403 permission_error (and possibly all 403s from auth endpoints) to auth_permanent failure reason, which should:

  1. Put the profile into cooldown/disabled state
  2. Clear lastGood for that provider
  3. Rotate to the next available profile

Workaround

Manually delete the expired profile from auth-profiles.json and set lastGood to the valid profile for all agents.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions