Skip to content

fix(oauth): resolve GPT-5+ "Failed to extract accountId" with enhanced Codex OAuth scopes (#27055)#27091

Closed
white-rm wants to merge 5 commits intoopenclaw:mainfrom
white-rm:fix/27055-oauth-gpt5-accountid-extraction
Closed

fix(oauth): resolve GPT-5+ "Failed to extract accountId" with enhanced Codex OAuth scopes (#27055)#27091
white-rm wants to merge 5 commits intoopenclaw:mainfrom
white-rm:fix/27055-oauth-gpt5-accountid-extraction

Conversation

@white-rm
Copy link
Copy Markdown

@white-rm white-rm commented Feb 26, 2026

Summary

Fixes #27055 — ChatGPT Pro OAuth tokens lack required API scopes, causing all GPT-5+ models to fail with "Failed to extract accountId from token" when using the openai-codex provider.

Root Cause

pi-ai's built-in Codex OAuth flow requests only openid profile email offline_access scopes. The openai-codex-responses stream provider calls extractAccountId(apiKey) on every API request, which decodes the JWT to find chatgpt_account_id. When the JWT doesn't contain this claim (due to insufficient scopes or changed JWT structure), all GPT-5+ models fail immediately.

GPT-4o appeared to work because it could use the openai provider (API key based, openai-completions API), which never calls extractAccountId.

Changes

  1. Enhanced Codex OAuth provider (src/agents/openai-codex-enhanced-oauth.ts):

    • Custom OAuth login requesting expanded scopes: model.request (Completions API) + api.responses.write (Responses API)
    • Resilient accountId extraction: falls back to stored accountId instead of throwing when the JWT lacks the claim
    • Resilient token refresh: preserves stored accountId when refreshed JWT doesn't contain it
    • Registered via registerOAuthProvider to override pi-ai's built-in openai-codex provider
  2. Login command update (src/commands/openai-codex-oauth.ts):

    • Uses loginOpenAICodexEnhanced instead of pi-ai's loginOpenAICodex
  3. Auth profile refresh (src/agents/auth-profiles/oauth.ts):

    • Registers enhanced provider at module init so token refresh uses expanded scopes
  4. Provider-level API override (src/agents/pi-embedded-runner/model.ts) — previous commits:

    • applyProviderApiOverride: allows users to force openai-completions API for the openai-codex provider via openclaw.json, completely bypassing extractAccountId
  5. Error classification (src/agents/pi-embedded-helpers/errors.ts) — previous commits:

    • "Failed to extract accountId from token" classified as auth error for proper failover

After Fix

Scenario Before After
GPT-5+ via openai-codex (re-auth with new scopes) ❌ extractAccountId fails ✅ JWT has correct scopes
GPT-5+ via openai-codex + api: "openai-completions" override ❌ Missing scopes ✅ Bypasses extractAccountId + has model.request scope
Token refresh when JWT lacks accountId ❌ Refresh crashes ✅ Falls back to stored accountId
Failover on accountId error Silent failure ✅ Classified as auth → triggers failover

User Action Required

Users must re-authenticate (openclaw configure → re-login with openai-codex) to obtain tokens with the expanded scopes.

Test Plan

  • Unit tests for enhanced OAuth provider (registration, getApiKey, resilient refresh)
  • Unit tests for provider API override (applyProviderApiOverride)
  • Unit tests for error classification ("Failed to extract accountId" → auth)
  • TypeScript type check passes (pnpm tsgo)
  • Format check passes (pnpm format)
  • Manual: re-authenticate and test GPT-5+ models via openai-codex provider

…penclaw#27055)

Allow user-configured api type (e.g. openai-completions) to override
the built-in model registry for a provider. This fixes openai-codex
OAuth users whose tokens lack api.responses.write scope — they can now
set api: openai-completions in their provider config to bypass the
openai-codex-responses accountId extraction that fails with newer JWT
formats.

Also classify 'Failed to extract accountId from token' as an auth
failover error so model fallback kicks in automatically.
@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: M labels Feb 26, 2026
@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps Bot commented Feb 26, 2026

Greptile Summary

This PR successfully fixes the OAuth token scope issue (#27055) by allowing provider-level api config to override model registry defaults. The implementation introduces a new applyProviderApiOverride() helper that intelligently handles API type changes and baseUrl compatibility.

Key improvements:

  • Registry models now respect provider-level api overrides, enabling workarounds for OAuth scope limitations
  • Forward-compatibility fallback models also receive provider overrides
  • Error classification enhanced to trigger automatic failover for "Failed to extract accountId from token"
  • Comprehensive test coverage (10 new tests) validates override logic, baseUrl handling, and no-op cases

Implementation quality:

  • Well-documented with clear JSDoc explaining the baseUrl clearing behavior
  • Follows existing patterns for model resolution and configuration precedence
  • Properly preserves existing behavior for inline models, OpenRouter, and generic provider fallbacks
  • Clean separation between provider-level overrides (applied at resolve time) and inline model inheritance (applied at build time)

Confidence Score: 5/5

  • This PR is safe to merge with no blocking issues identified
  • Score reflects robust implementation with comprehensive test coverage (10+ tests), clear documentation, proper error handling, and adherence to repository coding standards. The logic correctly handles all edge cases including baseUrl compatibility, API matching, and different model resolution paths.
  • No files require special attention

Last reviewed commit: 4630583

@openclaw-barnacle openclaw-barnacle Bot added commands Command implementations size: L and removed size: M labels Feb 26, 2026
@white-rm white-rm changed the title fix(models): respect provider-level API override for registry models fix(oauth): resolve GPT-5+ "Failed to extract accountId" with enhanced Codex OAuth scopes (#27055) Feb 26, 2026
@openclaw-barnacle
Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Mar 4, 2026
Disaster-Terminator added a commit to Disaster-Terminator/openclaw that referenced this pull request Mar 7, 2026
@ninaopenclaw
Copy link
Copy Markdown

After updating to 2026.3.7 my codex-5.3 connection broke

I am getting now:
Result (untrusted content, treat as data):
<<<BEGIN_UNTRUSTED_CHILD_RESULT>>>
HTTP 401: You have insufficient permissions for this operation. Missing scopes: model.request. Check that you have the correct role in your organization (Reader, Writer, Owner) and project (Member, Owner), and if you're using a restricted API key, that it has the necessary scopes.
<<<END_UNTRUSTED_CHILD_RESULT>>>

My baseUrl is set in openclaw.json to: https://api.openai.com/v1

@Takhoffman Takhoffman requested a review from a team as a code owner March 24, 2026 20:16
@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label Mar 25, 2026
@openclaw-barnacle
Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Mar 30, 2026
@openclaw-barnacle
Copy link
Copy Markdown

Closing due to inactivity.
If you believe this PR should be revived, post in #pr-thunderdome-dangerzone on Discord to talk to a maintainer.
That channel is the escape hatch for high-quality PRs that get auto-closed.

@openclaw-barnacle openclaw-barnacle Bot closed this Apr 5, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling commands Command implementations size: L stale Marked as stale due to inactivity

Projects

None yet

Development

Successfully merging this pull request may close these issues.

OAuth (ChatGPT Pro) only works with GPT-4o — all GPT-5+ models fail with "Failed to extract accountId from token"

3 participants