can1357/oh-my-pi · error · AIError.OAuthError

Device authorization response missing required fields

Error message

Device authorization response missing required fields

What it means

Thrown by loginOpenAICodexDevice when the device-authorization initiation returned HTTP 200 but the JSON payload lacks the required device_auth_id or user_code fields. Without these the CLI can neither display the code for the user nor poll for the token, so it fails fast with kind='validation'.

Source

Thrown at packages/ai/src/registry/oauth/openai-codex.ts:272

		body: JSON.stringify({ client_id: CLIENT_ID }),
		signal: AbortSignal.timeout(TOKEN_REQUEST_TIMEOUT_MS),
	});

	if (!initResponse.ok) {
		throw new AIError.OAuthError(`Device authorization initiation failed: ${initResponse.status}`, {
			kind: "device-auth",
			status: initResponse.status,
		});
	}

	const initData = (await initResponse.json()) as {
		device_auth_id?: string;
		user_code?: string;
		interval?: string | number;
	};

	if (!initData.device_auth_id || !initData.user_code) {
		throw new AIError.OAuthError("Device authorization response missing required fields", { kind: "validation" });
	}

	const userCode = initData.user_code;
	const pollIntervalMs =
		(typeof initData.interval === "number"
			? initData.interval
			: parseInt(String(initData.interval ?? "5"), 10) || 5) *
			1000 +
		DEVICE_POLL_SAFETY_MARGIN_MS;

	ctrl.onAuth?.({
		url: DEVICE_AUTH_URL,
		instructions: `Enter code: ${userCode}`,
	});

	ctrl.onProgress?.(`Waiting for browser authorization (code: ${userCode})…`);

	for (let poll = 0; poll < DEVICE_MAX_POLLS; poll++) {

View on GitHub (pinned to 9690622007)

Solutions

  1. Update the CLI so the expected field names match the current OpenAI device-auth API
  2. Inspect what the endpoint actually returns (curl with the same payload) to spot proxies or schema changes
  3. Disable/bypass intercepting proxies or VPNs and retry the login
  4. If OpenAI wrapped an error in a 200 body, wait and retry or check OpenAI status

Example fix

null
Defensive patterns

Strategy: validation

Validate before calling

// probe the device-auth endpoint shape before the full login
const res = await fetch(DEVICE_AUTH_URL, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ client_id: CLIENT_ID }) });
const body = await res.json().catch(() => null);
if (!body || typeof body.device_auth_id !== 'string' || typeof body.user_code !== 'string') {
  throw new Error('Unexpected device-auth response shape — update CLI or check proxy interference');
}

Type guard

function isDeviceAuthInit(d: unknown): d is { device_auth_id: string; user_code: string; interval?: string | number } {
  const v = d as Record<string, unknown> | null;
  return !!v && typeof v.device_auth_id === 'string' && typeof v.user_code === 'string';
}

Try / catch

try {
  const auth = await loginOpenAICodexDevice();
} catch (e) {
  if (e instanceof AIError.OAuthError && e.kind === 'validation' && e.message.includes('Device authorization response')) {
    // update CLI / bypass proxy / retry
  } else throw e;
}

Prevention

When it happens

Trigger: OpenAI returns a 200 response whose body is an error object, a different schema (renamed fields after an API change), or an empty/HTML body misinterpreted as JSON — e.g. an intercepted response from a proxy or captive portal.

Common situations: Outdated CLI after OpenAI renamed device-auth response fields; network middleware (corporate proxy, antivirus) returning a 200 error page; OpenAI returning 200-wrapped errors under load.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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