Skip to content

Codex OAuth login creates fresh named profile but runtime keeps preferring stale openai-codex:default #57286

Description

@jonathanadams96

Summary

After a native openclaw models auth login --provider openai-codex flow in a remote/VPS setup, OpenClaw creates a fresh named OAuth profile (for example openai-codex:<email-profile>), but runtime/session selection can continue using the stale openai-codex:default profile.

This leads to repeated Codex auth failures like:

  • refresh_token_reused
  • model fallback to Anthropic Sonnet

The problem persists even after:

  • successful native re-auth
  • gateway restart
  • native auth-order override preferring the fresh named profile

Environment

  • OpenClaw: 2026.3.24
  • Primary model: openai-codex/gpt-5.4
  • Fallback: anthropic/claude-sonnet-4-6
  • Runtime: remote/VPS, Discord channel sessions, Gateway running as system service
  • Auth flow used: native OpenClaw CLI, not manual file edits

What I expected

Running the native auth flow should either:

  1. refresh/replace the effective Codex auth profile cleanly, or
  2. create a new profile and make runtime consistently prefer it

After restart, both agents/sessions should use the fresh Codex profile without hitting refresh errors.

What actually happened

1. Native login creates a fresh named profile

Running:

openclaw models auth login --provider openai-codex

completed successfully and reported a fresh profile like:

  • openai-codex:<email-profile>

2. Runtime still preferred stale default

models status showed both profiles available:

  • openai-codex:default (expires in 0m)
  • openai-codex:<email-profile> (fresh, expires in 10d)

But runtime/session state still reported:

  • auth profile: openai-codex:default

3. Codex refresh kept failing

Logs showed repeated failures:

[openai-codex] Token refresh failed: 401 {
  "error": {
    "message": "Your refresh token has already been used to generate a new access token. Please try signing in again.",
    "type": "invalid_request_error",
    "code": "refresh_token_reused"
  }
}

and fallback decisions like:

[model-fallback/decision] model fallback decision: decision=candidate_failed requested=openai-codex/gpt-5.4 candidate=openai-codex/gpt-5.4 reason=auth next=anthropic/claude-sonnet-4-6

4. Native auth-order override did not fully recover runtime selection

I then used the native auth-order command for both agents:

openclaw models --agent main auth order set --provider openai-codex openai-codex:<email-profile> openai-codex:default
openclaw models --agent workspace auth order set --provider openai-codex openai-codex:<email-profile> openai-codex:default

This updated order overrides correctly.

However:

  • lastGood still pointed at openai-codex:default
  • current session status still reported openai-codex:default
  • refresh_token_reused errors continued in gateway logs

Why this seems like a distinct bug class

There are already issues around:

  • OAuth refresh races
  • auth state not persisted correctly
  • remote/manual OAuth handling

But this appears to add a more specific profile-selection/migration problem:

  • native login writes fresh creds into a new named profile
  • stale default remains present
  • runtime still anchors on stale default / lastGood
  • native order override is not enough to fully switch active runtime usage

Impact

  • user sees intermittent or silent fallback to Sonnet instead of Codex
  • manual re-auth appears successful but does not fully fix runtime behavior
  • remote/VPS setups become especially confusing because the auth flow seems to succeed while runtime still uses stale state

Suggested fix areas

  1. After successful openclaw models auth login --provider openai-codex, reconcile runtime preference automatically:

    • promote the fresh named profile to effective default, or
    • update lastGood, or
    • invalidate/remove stale openai-codex:default if it is expired/reused
  2. Ensure auth-order override is actually honored by live runtime/session auth selection

  3. If runtime keeps using a stale expired profile while a fresh OAuth profile exists, log that explicitly instead of silently falling back

Extra note

This report is based on the native supported CLI flow and native auth-order commands only. The underlying failure remained reproducible even after returning to the supported path.

Metadata

Metadata

Assignees

Labels

close:duplicateClosed as duplicatededupe:childDuplicate issue/PR child in dedupe cluster

Type

No type

Fields

Priority

None yet

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions