{"record":{"id":"a07cb86195928bd1","repo":"stablyai/orca","slug":"codex-login-completed-but-orca-could-not-resolve","errorCode":null,"errorMessage":"Codex login completed, but Orca could not resolve the account email.","messagePattern":"Codex login completed, but Orca could not resolve the account email\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/main/codex-accounts/service.ts","lineNumber":784,"sourceCode":"    const authPath = join(resolve(trimmed), 'auth.json')\n    if (!existsSync(authPath)) {\n      throw new Error(\n        `No Codex credentials found in ${resolve(trimmed)}. Run \\`codex login\\` into this directory first.`\n      )\n    }\n    const trustedHome = this.assertManagedHomePath(managedHomePath, accountId)\n    writeFileAtomically(join(trustedHome, 'auth.json'), readFileSync(authPath, 'utf-8'), {\n      mode: 0o600\n    })\n  }\n\n  private async persistCapturedCodexAccount(\n    accountId: string,\n    managedHome: ManagedHomeLocation\n  ): Promise<CodexRateLimitAccountsState> {\n    const identity = this.readIdentityFromHome(managedHome.managedHomePath, accountId)\n    if (!identity.email) {\n      throw new Error('Codex login completed, but Orca could not resolve the account email.')\n    }\n\n    const now = Date.now()\n    const account: CodexManagedAccount = {\n      id: accountId,\n      email: identity.email,\n      managedHomePath: managedHome.managedHomePath,\n      managedHomeRuntime: managedHome.managedHomeRuntime,\n      wslDistro: managedHome.wslDistro,\n      wslLinuxHomePath: managedHome.wslLinuxHomePath,\n      providerAccountId: identity.providerAccountId,\n      workspaceLabel: identity.workspaceLabel,\n      workspaceAccountId: identity.workspaceAccountId,\n      createdAt: now,\n      updatedAt: now,\n      lastAuthenticatedAt: now\n    }\n","sourceCodeStart":766,"sourceCodeEnd":802,"githubUrl":"https://github.com/stablyai/orca/blob/1136503c6a231a16dce8f921f6fadb63d181e8db/src/main/codex-accounts/service.ts#L766-L802","documentation":"Thrown by persistCapturedCodexAccount after doAddAccount / doAddAccountFromHome. readIdentityFromHome successfully read auth.json and parsed the OAuth credentials, but resolveIdentityFromCredentials (service.ts:1799) could not extract an email from the id_token JWT claims (no top-level 'email' and no email in the profile claim namespace). Orca keys managed accounts by email, so it refuses to persist an account without one.","triggerScenarios":"codex login completed and wrote auth.json, but the issued id_token lacks an email claim. Reached via addAccount() (service.ts:728) or addAccountFromHome() (service.ts:747).","commonSituations":"The OAuth provider issued a token without an email scope/claim (e.g. a service/workspace account, SSO with email hidden, or an atypical ChatGPT workspace token). A corrupt or partial auth.json can also yield empty identity fields.","solutions":["Re-authenticate ensuring the email scope is granted; re-run `codex login` (or re-trigger addAccount) so a token with an email claim is issued.","Inspect the id_token in the managed home's auth.json (JWT payload) to confirm whether an email claim is present; if not, the account type/provider config is the cause.","If the token genuinely has no email, Orca cannot manage this identity — use the system-default account instead."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"// Decode the id_token email claim before persisting (best-effort pre-check).\nfunction idTokenHasEmail(authJson: string): boolean {\n  try {\n    const idToken = JSON.parse(authJson).id_token ?? JSON.parse(authJson).idToken\n    const payload = JSON.parse(Buffer.from(idToken.split('.')[1], 'base64').toString('utf-8'))\n    return Boolean(payload.email ?? payload['https://api.openai.com/profile']?.email)\n  } catch { return false }\n}","typeGuard":null,"tryCatchPattern":"try {\n  await service.addAccount(target)\n} catch (error) {\n  if (error instanceof Error && error.message.includes('could not resolve the account email')) {\n    // prompt re-login; the issued token lacked the email claim\n  } else throw error\n}","preventionTips":["Ensure the OAuth email scope is granted during codex login.","If the account type never carries an email, use the system-default identity instead."],"tags":["codex-accounts","oauth","identity","jwt","add-account"],"backgroundTag":null,"analyzedSha":"1136503c6a231a16dce8f921f6fadb63d181e8db","analyzedAt":"2026-08-12T23:15:58.167Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}