{"record":{"id":"bf83a2f2d84d2e2e","repo":"can1357/oh-my-pi","slug":"codex-security-cloud-requires-an-openai-codex-chat","errorCode":null,"errorMessage":"Codex Security cloud requires an openai-codex ChatGPT OAuth credential","messagePattern":"Codex Security cloud requires an openai-codex ChatGPT OAuth credential","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/coding-agent/src/security/cloud.ts","lineNumber":190,"sourceCode":"\t}\n}\n\ninterface CloudRequestOptions {\n\tmethod?: \"GET\" | \"POST\";\n\tquery?: Record<string, string | number | undefined>;\n\tbody?: JsonObject | ((accessToken: string) => JsonObject);\n\tsignal?: AbortSignal;\n}\n\nexport class CodexSecurityCloudClient {\n\treadonly #authStorage: AuthStorage;\n\treadonly #account: SecurityAccountRef;\n\treadonly #baseUrl: string;\n\treadonly #fetch: CodexSecurityCloudFetch;\n\n\tconstructor(options: CodexSecurityCloudClientOptions) {\n\t\tif (options.account.provider !== \"openai-codex\") {\n\t\t\tthrow new Error(\"Codex Security cloud requires an openai-codex ChatGPT OAuth credential\");\n\t\t}\n\t\tthis.#authStorage = options.authStorage;\n\t\tthis.#account = options.account;\n\t\tthis.#baseUrl = (options.baseUrl ?? DEFAULT_CLOUD_BASE_URL).replace(/\\/$/, \"\");\n\t\tthis.#fetch = options.fetch ?? fetch;\n\t}\n\n\tasync #request(pathname: string, options: CloudRequestOptions = {}): Promise<JsonObject> {\n\t\tconst url = new URL(`${this.#baseUrl}/${pathname.replace(/^\\//, \"\")}`);\n\t\tfor (const [key, value] of Object.entries(options.query ?? {})) {\n\t\t\tif (value !== undefined) url.searchParams.set(key, String(value));\n\t\t}\n\t\tfor (let attempt = 0; attempt < 2; attempt += 1) {\n\t\t\tconst access = await resolveExactSecurityOAuthAccess(this.#authStorage, this.#account, {\n\t\t\t\tforceRefresh: attempt > 0,\n\t\t\t\tsignal: options.signal,\n\t\t\t});\n\t\t\tconst body = typeof options.body === \"function\" ? options.body(access.accessToken) : options.body;","sourceCodeStart":172,"sourceCodeEnd":208,"githubUrl":"https://github.com/can1357/oh-my-pi/blob/969062200754ea02cfac922e5ebb8c608c079e15/packages/coding-agent/src/security/cloud.ts#L172-L208","documentation":"The CodexSecurityCloud client constructor only accepts accounts whose provider is exactly \"openai-codex\" (ChatGPT OAuth). Constructing it with any other provider's SecurityAccountRef throws immediately, before any network call.","triggerScenarios":"new CodexSecurityCloudClient({ account: { provider: \"openai\" | \"anthropic\" | ..., credentialId }, ... }) — i.e. wiring a non-ChatGPT credential into the Codex Security cloud client.","commonSituations":"Generic account-selection code passing whichever provider was picked by ambiguous-account logic; typos like \"openai\" vs \"openai-codex\"; reusing a client builder across providers.","solutions":["Select/pin an openai-codex OAuth credential before constructing the client","Fix the provider string to exactly \"openai-codex\"","Guard construction: only build the cloud client when account.provider === \"openai-codex\""],"exampleFix":"// before\nconst client = new CodexSecurityCloudClient({ account: selectedAccount, authStorage });\n// after\nif (selectedAccount.provider !== \"openai-codex\") {\n  throw new Error(\"Codex Security cloud needs an openai-codex credential\");\n}\nconst client = new CodexSecurityCloudClient({ account: selectedAccount, authStorage });","handlingStrategy":"validation","validationCode":"if (account.provider !== \"openai-codex\") {\n  throw new Error(`Codex Security cloud needs openai-codex, got ${account.provider}`);\n}\nconst client = new CodexSecurityCloudClient({ account, authStorage });","typeGuard":"function isCodexAccount(a: { provider: string }): a is { provider: \"openai-codex\" } {\n  return a.provider === \"openai-codex\";\n}","tryCatchPattern":"try {\n  const client = new CodexSecurityCloudClient({ account, authStorage });\n} catch (err) {\n  if (err.message.includes(\"openai-codex\")) {\n    // re-select an openai-codex credential before constructing\n  } else throw err;\n}","preventionTips":["Filter account selection to provider === \"openai-codex\" before building the client","Use exact provider constants, not free-form strings","Type the account ref with a literal provider union where possible"],"tags":["oauth","configuration","provider-mismatch"],"backgroundTag":"provider-mismatch","analyzedSha":"969062200754ea02cfac922e5ebb8c608c079e15","analyzedAt":"2026-08-31T10:29:35.737Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}