tinyhumansai/openhuman · error · Error

OPENAI_CODEX_OAUTH_MISSING_AUTH_URL

OPENAI_CODEX_OAUTH_MISSING_AUTH_URL

Error message

OPENAI_CODEX_OAUTH_MISSING_AUTH_URL

What it means

Thrown by startOpenAiCodexOAuth() after the core RPC 'openhuman.inference_openai_oauth_start' resolves but the result's authUrl field is missing, empty, or whitespace-only after trimming. The OpenHuman Rust core is expected to build a ChatGPT/OpenAI OAuth authorize URL (from its client-id config) and return it for an external-browser flow; this guard catches a core that answered the RPC without producing one. It is a client-side contract check, not a network error — the RPC itself succeeded.

Solutions

  1. Check the core log output for the inference/OAuth start handler — it usually logs why no authUrl was built (missing client id / endpoint config).
  2. Verify your core is current: the UI and openhuman-core must be from the same release; restart or update the core (restartCoreProcess or reinstall) so inference_openai_oauth_start returns auth_url.
  3. Confirm the Codex/OpenAI OAuth settings exist in Settings > AI providers, or that the .env / config TOML the core loads has the OAuth client values it needs.
  4. If running a standalone core (openhuman-core serve), point the app at the matching version or run the bundled desktop core instead.

Example fix

// before
const res = await callCoreRpc<{ result: OpenAiCodexOAuthStartResult }>({
  method: 'openhuman.inference_openai_oauth_start',
  params: {},
});
const authUrl = res?.result?.authUrl?.trim();
if (!authUrl) {
  throw new Error(OPENAI_CODEX_OAUTH_MISSING_AUTH_URL);
}

// after — surface the raw core result to make triage possible
if (!authUrl) {
  throw new Error(
    `${OPENAI_CODEX_OAUTH_MISSING_AUTH_URL} (core result: ${JSON.stringify(res?.result ?? null)})`
  );
}
Defensive patterns

Strategy: try-catch

Validate before calling

import { callCoreRpc } from '../coreRpcClient';

async function canStartCodexOAuth(): Promise<boolean> {
  try {
    const res = await callCoreRpc<{ result?: { authUrl?: string } }>({
      method: 'openhuman.inference_openai_oauth_start',
      params: {},
    });
    return Boolean(res?.result?.authUrl?.trim());
  } catch {
    return false;
  }
}

Type guard

function hasAuthUrl(res: unknown): res is { authUrl: string } {
  return typeof (res as { authUrl?: unknown })?.authUrl === 'string'
    && (res as { authUrl: string }).authUrl.trim().length > 0;
}

Try / catch

try {
  const { authUrl } = await startOpenAiCodexOAuth();
  await openExternal(authUrl);
} catch (e) {
  if (e instanceof Error && e.message === 'OPENAI_CODEX_OAUTH_MISSING_AUTH_URL') {
    notify('Could not start Codex sign-in — update/restart the Core and retry.');
  } else throw e;
}

Prevention

When it happens

Trigger: Calling startOpenAiCodexOAuth() when: the core's Codex OAuth client credentials are unset or malformed; the core version predates inference_openai_oauth_start returning auth_url; the core handler hit an internal config error and returned an empty result object instead of an RPC error.

Common situations: Fresh desktop install where the backend/api config block is incomplete; running the UI against an older or standalone core binary (openhuman-core serve) that lacks the OAuth start handler's full response; a config migration wiped provider OAuth settings; environment (.env) missing required OAuth variables the core reads at startup.

Related errors


AI-assisted analysis of tinyhumansai/openhuman@7491200858 (2026-08-17). Data as JSON: /api/errors/6b6f7d3cc602eae0. Report an issue: GitHub.

Appendix: source

Thrown at app/src/services/api/aiSettingsApi.ts:726

/** Clear a stored API key. */
export async function clearCloudProviderKey(slug: string): Promise<void> {
  if (slug === 'openhuman') {
    return;
  }
  // Clear the new-style key. Legacy bare-slug entries are left as-is
  // since we can't be sure they aren't used by other things.
  await authRemoveProviderCredentials({ provider: authKeyForSlug(slug), profile: 'default' });
}

export async function startOpenAiCodexOAuth(): Promise<OpenAiCodexOAuthStartResult> {
  const res = await callCoreRpc<{ result: OpenAiCodexOAuthStartResult }>({
    method: 'openhuman.inference_openai_oauth_start',
    params: {},
  });
  const authUrl = res?.result?.authUrl?.trim();
  if (!authUrl) {
    throw new Error(OPENAI_CODEX_OAUTH_MISSING_AUTH_URL);
  }
  return res.result;
}

export async function completeOpenAiCodexOAuth(callbackUrl: string): Promise<void> {
  const callback = callbackUrl.trim();
  if (!callback) {
    throw new Error(OPENAI_CODEX_OAUTH_MISSING_CALLBACK_URL);
  }
  await callCoreRpc({
    method: 'openhuman.inference_openai_oauth_complete',
    params: { callback_url: callback },
  });
}

export async function importOpenAiCodexCliAuth(): Promise<void> {
  await callCoreRpc({ method: 'openhuman.inference_openai_oauth_import_codex_cli', params: {} });
}

View on GitHub (pinned to 7491200858)