stablyai/orca · error · Error

Orca cannot add a Codex OAuth account while ~/.codex/config.

Error message

Orca cannot add a Codex OAuth account while ~/.codex/config.toml pins the custom provider ${JSON.stringify(modelProvider)}. Keep using the system-default account for this provider, or remove model_provider (or set it to "openai") before adding an OAuth account. Orca left your config unchanged.

What it means

Thrown by assertOAuthAccountAddAllowed, which runs before any OAuth login during doAddAccount/doAddAccountFromHome. If the user's ~/.codex/config.toml sets a top-level model_provider other than 'openai' (or absent), Orca refuses to add an OAuth account. Mirroring a custom-provider pin into an OAuth managed home would make the new OAuth credentials inert, so the guard fails fast and leaves the user's config untouched.

Source

Thrown at src/main/codex-accounts/service.ts:1347

        sourceHooksPath: `${wslHome}/.codex/hooks.json`
      }
    } catch (error) {
      console.warn('[codex-accounts] Failed to read WSL canonical config:', error)
      return null
    }
  }

  private assertOAuthAccountAddAllowed(canonicalConfig: CanonicalCodexConfig | null): void {
    const modelProvider = canonicalConfig
      ? readCodexTopLevelModelProvider(canonicalConfig.contents)
      : null
    if (!modelProvider || modelProvider === 'openai') {
      return
    }

    // Why: mirroring a custom-provider pin into an OAuth managed home makes
    // the new OAuth credentials inert; fail before login and leave user config intact.
    throw new Error(
      `Orca cannot add a Codex OAuth account while ~/.codex/config.toml pins the custom provider ${JSON.stringify(modelProvider)}. Keep using the system-default account for this provider, or remove model_provider (or set it to "openai") before adding an OAuth account. Orca left your config unchanged.`
    )
  }

  private writeManagedConfig(managedHomePath: string, contents: string): void {
    const configPath = join(managedHomePath, 'config.toml')
    try {
      if (existsSync(configPath) && readFileSync(configPath, 'utf-8') === contents) {
        return
      }
    } catch {
      // Why: a read error must not make a stale config look current; atomic write owns ACL repair and error surfacing.
    }
    writeFileAtomically(configPath, contents)
  }

  private getManagedAccountsRoot(): string {
    const root = join(app.getPath('userData'), 'codex-accounts')

View on GitHub (pinned to 1136503c6a)

Solutions

  1. Remove the model_provider line (or set model_provider = "openai") in ~/.codex/config.toml, then retry the add.
  2. Keep using the system-default account for that custom provider instead of adding an OAuth account.
  3. If you need both, manage the custom-provider account outside Orca's OAuth flow.

Example fix

# before: ~/.codex/config.toml
model_provider = "my-gateway"
# then: service.addAccount()  -> throws [915]

# after: unset the pin (or set openai) before adding the OAuth account
# model_provider = "openai"
service.addAccount()
Defensive patterns

Strategy: validation

Validate before calling

// Check the canonical config provider before adding an OAuth account.
import { readFileSync, existsSync } from 'node:fs'
import { join } from 'node:path'
import { homedir } from 'node:os'
import { readCodexTopLevelModelProvider } from '../codex/codex-model-provider-config'
const cfg = join(homedir(), '.codex', 'config.toml')
if (existsSync(cfg)) {
  const provider = readCodexTopLevelModelProvider(readFileSync(cfg, 'utf-8'))
  if (provider && provider !== 'openai') {
    throw new Error(`Remove or set model_provider=openai before adding an OAuth account (got ${provider}).`)
  }
}
await service.addAccount(target)

Type guard

const blocksOAuthAdd = (provider: string | null): boolean =>
  provider !== null && provider !== 'openai'

Try / catch

try {
  await service.addAccount(target)
} catch (error) {
  if (error instanceof Error && error.message.includes('pins the custom provider')) {
    // instruct user to remove model_provider (or set openai) then retry
  } else throw error
}

Prevention

When it happens

Trigger: Calling addAccount() or addAccountFromHome() while readCodexTopLevelModelProvider(canonicalConfig.contents) returns a provider name that is neither null nor 'openai'.

Common situations: User configured a custom/an API-key provider (e.g. a third-party model gateway) in ~/.codex/config.toml via model_provider, then tries to add an OAuth (ChatGPT) account. Orca blocks this to avoid a broken half-OAuth-half-custom setup.

Related errors


AI-assisted analysis of stablyai/orca@1136503c6a (2026-08-12). Data as JSON: /api/errors/fe3fbfa6c9003260. Report an issue: GitHub.