can1357/oh-my-pi · error

Codex Security cloud requires an openai-codex ChatGPT OAuth

Error message

Codex Security cloud requires an openai-codex ChatGPT OAuth credential

What it means

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.

Source

Thrown at packages/coding-agent/src/security/cloud.ts:190

	}
}

interface CloudRequestOptions {
	method?: "GET" | "POST";
	query?: Record<string, string | number | undefined>;
	body?: JsonObject | ((accessToken: string) => JsonObject);
	signal?: AbortSignal;
}

export class CodexSecurityCloudClient {
	readonly #authStorage: AuthStorage;
	readonly #account: SecurityAccountRef;
	readonly #baseUrl: string;
	readonly #fetch: CodexSecurityCloudFetch;

	constructor(options: CodexSecurityCloudClientOptions) {
		if (options.account.provider !== "openai-codex") {
			throw new Error("Codex Security cloud requires an openai-codex ChatGPT OAuth credential");
		}
		this.#authStorage = options.authStorage;
		this.#account = options.account;
		this.#baseUrl = (options.baseUrl ?? DEFAULT_CLOUD_BASE_URL).replace(/\/$/, "");
		this.#fetch = options.fetch ?? fetch;
	}

	async #request(pathname: string, options: CloudRequestOptions = {}): Promise<JsonObject> {
		const url = new URL(`${this.#baseUrl}/${pathname.replace(/^\//, "")}`);
		for (const [key, value] of Object.entries(options.query ?? {})) {
			if (value !== undefined) url.searchParams.set(key, String(value));
		}
		for (let attempt = 0; attempt < 2; attempt += 1) {
			const access = await resolveExactSecurityOAuthAccess(this.#authStorage, this.#account, {
				forceRefresh: attempt > 0,
				signal: options.signal,
			});
			const body = typeof options.body === "function" ? options.body(access.accessToken) : options.body;

View on GitHub (pinned to 9690622007)

Solutions

  1. Select/pin an openai-codex OAuth credential before constructing the client
  2. Fix the provider string to exactly "openai-codex"
  3. Guard construction: only build the cloud client when account.provider === "openai-codex"

Example fix

// before
const client = new CodexSecurityCloudClient({ account: selectedAccount, authStorage });
// after
if (selectedAccount.provider !== "openai-codex") {
  throw new Error("Codex Security cloud needs an openai-codex credential");
}
const client = new CodexSecurityCloudClient({ account: selectedAccount, authStorage });
Defensive patterns

Strategy: validation

Validate before calling

if (account.provider !== "openai-codex") {
  throw new Error(`Codex Security cloud needs openai-codex, got ${account.provider}`);
}
const client = new CodexSecurityCloudClient({ account, authStorage });

Type guard

function isCodexAccount(a: { provider: string }): a is { provider: "openai-codex" } {
  return a.provider === "openai-codex";
}

Try / catch

try {
  const client = new CodexSecurityCloudClient({ account, authStorage });
} catch (err) {
  if (err.message.includes("openai-codex")) {
    // re-select an openai-codex credential before constructing
  } else throw err;
}

Prevention

When it happens

Trigger: new CodexSecurityCloudClient({ account: { provider: "openai" | "anthropic" | ..., credentialId }, ... }) — i.e. wiring a non-ChatGPT credential into the Codex Security cloud client.

Common situations: 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.

Related errors


AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31). Data as JSON: /api/errors/bf83a2f2d84d2e2e. Report an issue: GitHub.