srbhr/Resume-Matcher · error · Error

Failed to load API key status (status ${res.status}).

Error message

Failed to load API key status (status ${res.status}).

What it means

fetchApiKeyStatus calls GET /config/api-keys (which reports per-provider key presence/validity, never key material) and throws this Error for any non-ok response. It's the standard config-fetcher pattern: only the status code is preserved. A failure here means the backend refused or failed the API-key status query, not that any key is invalid.

Source

Thrown at apps/frontend/lib/api/config.ts:483

export const API_KEY_PROVIDER_INFO: Record<ApiKeyProvider, { name: string; description: string }> =
  {
    openai: { name: 'OpenAI', description: 'GPT-4, GPT-4o, etc.' },
    azure_foundry: { name: 'Azure AI Foundry', description: 'Azure AI Inference models' },
    anthropic: { name: 'Anthropic', description: 'Claude 3.5, Claude 4, etc.' },
    google: { name: 'Google', description: 'Gemini 1.5, Gemini 2, etc.' },
    openrouter: { name: 'OpenRouter', description: 'Access multiple providers' },
    deepseek: { name: 'DeepSeek', description: 'DeepSeek chat models' },
    groq: { name: 'Groq', description: 'Llama, Mixtral, Gemma on Groq' },
    openai_compatible: { name: 'OpenAI-Compatible', description: 'Self-hosted / proxy endpoints' },
    ollama: { name: 'Ollama', description: 'Local Ollama server' },
  };

// Fetch API key status for all providers
export async function fetchApiKeyStatus(): Promise<ApiKeyStatusResponse> {
  const res = await apiFetch('/config/api-keys', { credentials: 'include' });

  if (!res.ok) {
    throw new Error(`Failed to load API key status (status ${res.status}).`);
  }

  return res.json();
}

// Update API keys for one or more providers
export async function updateApiKeys(keys: ApiKeysUpdateRequest): Promise<ApiKeysUpdateResponse> {
  const res = await apiFetch('/config/api-keys', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    credentials: 'include',
    body: JSON.stringify(keys),
  });

  if (!res.ok) {
    const data = await res.json().catch(() => ({}));
    throw new Error(data.detail || `Failed to update API keys (status ${res.status}).`);
  }

View on GitHub (pinned to 116f9cc3b0)

Solutions

  1. Decode the status: 401/403 → log in again; 404 → verify /api/v1/config/api-keys exists and rewrites target BACKEND_ORIGIN; 5xx → check backend logs and DB/key-store health.
  2. Curl the endpoint with the session cookie to isolate proxy vs backend.
  3. Ensure NEXT_PUBLIC_API_URL/BACKEND_ORIGIN are set consistently in the environment.
  4. In calling loaders (keyStatus etc.), catch and render a 'status unavailable' state so the settings page still works.

Example fix

// before
const status = await fetchApiKeyStatus();

// after
const status = await fetchApiKeyStatus().catch((e) => {
  console.warn('API key status unavailable', e);
  return EMPTY_KEY_STATUS; // all providers unknown
});
Defensive patterns

Strategy: fallback

Validate before calling

const sessionOk = document.cookie.includes('session');
if (!sessionOk) await refreshSession(); // avoid guaranteed 401

Type guard

function isApiKeyStatusResponse(x: unknown): x is ApiKeyStatusResponse {
  return typeof x === 'object' && x !== null && 'providers' in x;
}

Try / catch

try {
  status = await fetchApiKeyStatus();
} catch {
  status = null; // render 'unknown' state per provider
  setKeyStatusUnavailable(true);
}

Prevention

When it happens

Trigger: Non-2xx from GET /config/api-keys: 401/403 (expired credentials cookie or CSRF failure), 404 (route missing or NEXT_PUBLIC_API_URL/BACKEND_ORIGIN misconfigured so the proxy returns its own 404), 500 when the backend can't read its encrypted key store / DB, 502 when the backend is down.

Common situations: Settings page load while the backend is restarting; session timeout mid-browsing; database migration left the key store table missing; dev frontend started without the backend on :8000.

Related errors


AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28). Data as JSON: /api/errors/9af2b79408e4b9df. Report an issue: GitHub.