{"record":{"id":"fe3fbfa6c9003260","repo":"stablyai/orca","slug":"orca-cannot-add-a-codex-oauth-account-while-cod","errorCode":null,"errorMessage":"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.","messagePattern":"Orca cannot add a Codex OAuth account while ~/\\.codex/config\\.toml pins the custom provider (.+?)\\. 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\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/codex-accounts/service.ts","lineNumber":1347,"sourceCode":"        sourceHooksPath: `${wslHome}/.codex/hooks.json`\n      }\n    } catch (error) {\n      console.warn('[codex-accounts] Failed to read WSL canonical config:', error)\n      return null\n    }\n  }\n\n  private assertOAuthAccountAddAllowed(canonicalConfig: CanonicalCodexConfig | null): void {\n    const modelProvider = canonicalConfig\n      ? readCodexTopLevelModelProvider(canonicalConfig.contents)\n      : null\n    if (!modelProvider || modelProvider === 'openai') {\n      return\n    }\n\n    // Why: mirroring a custom-provider pin into an OAuth managed home makes\n    // the new OAuth credentials inert; fail before login and leave user config intact.\n    throw new Error(\n      `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.`\n    )\n  }\n\n  private writeManagedConfig(managedHomePath: string, contents: string): void {\n    const configPath = join(managedHomePath, 'config.toml')\n    try {\n      if (existsSync(configPath) && readFileSync(configPath, 'utf-8') === contents) {\n        return\n      }\n    } catch {\n      // Why: a read error must not make a stale config look current; atomic write owns ACL repair and error surfacing.\n    }\n    writeFileAtomically(configPath, contents)\n  }\n\n  private getManagedAccountsRoot(): string {\n    const root = join(app.getPath('userData'), 'codex-accounts')","sourceCodeStart":1329,"sourceCodeEnd":1365,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/codex-accounts/service.ts#L1329-L1365","documentation":"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.","triggerScenarios":"Calling addAccount() or addAccountFromHome() while readCodexTopLevelModelProvider(canonicalConfig.contents) returns a provider name that is neither null nor 'openai'.","commonSituations":"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.","solutions":["Remove the model_provider line (or set model_provider = \"openai\") in ~/.codex/config.toml, then retry the add.","Keep using the system-default account for that custom provider instead of adding an OAuth account.","If you need both, manage the custom-provider account outside Orca's OAuth flow."],"exampleFix":"# before: ~/.codex/config.toml\nmodel_provider = \"my-gateway\"\n# then: service.addAccount()  -> throws [915]\n\n# after: unset the pin (or set openai) before adding the OAuth account\n# model_provider = \"openai\"\nservice.addAccount()","handlingStrategy":"validation","validationCode":"// Check the canonical config provider before adding an OAuth account.\nimport { readFileSync, existsSync } from 'node:fs'\nimport { join } from 'node:path'\nimport { homedir } from 'node:os'\nimport { readCodexTopLevelModelProvider } from '../codex/codex-model-provider-config'\nconst cfg = join(homedir(), '.codex', 'config.toml')\nif (existsSync(cfg)) {\n  const provider = readCodexTopLevelModelProvider(readFileSync(cfg, 'utf-8'))\n  if (provider && provider !== 'openai') {\n    throw new Error(`Remove or set model_provider=openai before adding an OAuth account (got ${provider}).`)\n  }\n}\nawait service.addAccount(target)","typeGuard":"const blocksOAuthAdd = (provider: string | null): boolean =>\n  provider !== null && provider !== 'openai'","tryCatchPattern":"try {\n  await service.addAccount(target)\n} catch (error) {\n  if (error instanceof Error && error.message.includes('pins the custom provider')) {\n    // instruct user to remove model_provider (or set openai) then retry\n  } else throw error\n}","preventionTips":["Do not set model_provider to a custom gateway while using OAuth Codex accounts.","Surface this as a config-fix instruction in the UI, not a generic failure."],"tags":["codex-accounts","config","model-provider","oauth","add-account"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}