srbhr/Resume-Matcher · error · Error
Failed to load feature prompts (status ${res.status}).
Error message
Failed to load feature prompts (status ${res.status}). What it means
fetchFeaturePrompts performs GET /config/feature-prompts and throws this generic Error whenever the HTTP response is not ok. Like the other config fetchers it only surfaces the status code; the actual cause (auth, routing, backend failure) must be inferred from it. The typed FeaturePrompts result is only returned on a 2xx with a JSON body.
Source
Thrown at apps/frontend/lib/api/config.ts:369
code: 'missing_placeholders';
field: 'cover_letter_prompt' | 'outreach_message_prompt';
missing: string[];
}
export class FeaturePromptsError extends Error {
detail: FeaturePromptsValidationError;
constructor(detail: FeaturePromptsValidationError) {
super(`Invalid ${detail.field}: missing ${detail.missing.join(', ')}`);
this.name = 'FeaturePromptsError';
this.detail = detail;
}
}
export async function fetchFeaturePrompts(): Promise<FeaturePrompts> {
const res = await apiFetch('/config/feature-prompts', { credentials: 'include' });
if (!res.ok) {
throw new Error(`Failed to load feature prompts (status ${res.status}).`);
}
return res.json();
}
export async function updateFeaturePrompts(update: FeaturePromptsUpdate): Promise<FeaturePrompts> {
const res = await apiFetch('/config/feature-prompts', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
credentials: 'include',
body: JSON.stringify(update),
});
if (!res.ok) {
// Error path: body may be absent or malformed, so we tolerate parse
// failure. A fetch body is a one-shot stream — read it once and reuse
// for both the 422-special-case and the generic fallback.
const errBody = (await res.json().catch(() => ({}))) as {
detail?: FeaturePromptsValidationError | string;View on GitHub (pinned to 116f9cc3b0)
Solutions
- Check the status in the message: 401/403 → refresh the session; 404 → confirm /api/v1/config/feature-prompts exists on the backend and rewrites point at BACKEND_ORIGIN; 5xx → inspect backend logs.
- Curl the endpoint with the session cookie to separate proxy problems from backend problems.
- Verify frontend/backend versions are matched (endpoint present in the deployed backend).
- Handle the rejection where the callers (llmConfig/featureConfig/promptConfig/featurePrompts/keyStatus loaders) run so the page degrades gracefully.
Example fix
// before
const prompts = await fetchFeaturePrompts();
// after
let prompts: FeaturePrompts;
try {
prompts = await fetchFeaturePrompts();
} catch (e) {
console.warn('feature prompts unavailable, using defaults', e);
prompts = DEFAULT_FEATURE_PROMPTS; // fallback
} Defensive patterns
Strategy: fallback
Validate before calling
// Health-check the backend before dependent config fetches
const ping = await fetch('/api/v1/status', { credentials: 'include' });
if (!ping.ok) throw new Error('Backend unavailable, skip feature prompts load'); Type guard
function isFeaturePrompts(x: unknown): x is FeaturePrompts {
return typeof x === 'object' && x !== null && 'cover_letter_prompt' in x;
} Try / catch
try {
prompts = await fetchFeaturePrompts();
} catch {
prompts = DEFAULT_FEATURE_PROMPTS;
} Prevention
- Verify backend reachability before loading settings
- Ship default feature prompts as client-side fallback
- Match frontend and backend deployment versions
- Alert on 404s from proxied /api routes (proxy misconfiguration signal)
When it happens
Trigger: Non-2xx on GET /config/feature-prompts: 401/403 from expired credentials cookie or CSRF check, 404 because the backend route is missing or NEXT_PUBLIC_API_URL/BACKEND_ORIGIN proxying is wrong, 5xx when the backend cannot read its feature-prompt store (e.g. DB/config file unavailable).
Common situations: Opening Settings while the backend container is restarting (502 through the proxy); stale deployment where frontend and backend versions disagree and the endpoint moved; running the frontend without the backend on :8000 in local dev.
Related errors
- Failed to load prompt config (status ${res.status}).
- ${data.detail || Failed to update prompt config (status ${re
- ${message = errBody.detail or Failed to update feature promp
- Failed to load API key status (status ${res.status}).
- Failed to load LLM config (status ${res.status}).
AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28).
Data as JSON: /api/errors/42d2ee53a8ed77ad.
Report an issue: GitHub.