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
- 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.
- Curl the endpoint with the session cookie to isolate proxy vs backend.
- Ensure NEXT_PUBLIC_API_URL/BACKEND_ORIGIN are set consistently in the environment.
- 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
- Refresh session before long-lived settings pages fetch key status
- Health-check the backend before key management UI loads
- Treat unknown status as 'not configured', not as an error state
- Watch proxy logs for 404/502 on /api/v1/config/api-keys
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
- Failed to load prompt config (status ${res.status}).
- ${data.detail || Failed to update prompt config (status ${re
- Failed to load feature prompts (status ${res.status}).
- ${message = errBody.detail or Failed to update feature promp
- ${data.detail || Failed to update API keys (status ${res.sta
AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28).
Data as JSON: /api/errors/9af2b79408e4b9df.
Report an issue: GitHub.