srbhr/Resume-Matcher · error · Error
${message = errBody.detail or Failed to update feature promp
Error message
${message = errBody.detail or Failed to update feature prompts (status ${res.status}).} What it means
The generic branch of updateFeaturePrompts: for any non-422-missing_placeholders failure it builds a message from errBody.detail — string detail used as-is, object detail JSON.stringify'd (avoiding '[object Object]'), and this exact message as the final fallback when the body has no usable detail. It then throws a plain Error. It fires for auth failures, other 422 validation errors, 404 routing problems, and 5xx backend faults on PUT /config/feature-prompts.
Source
Thrown at apps/frontend/lib/api/config.ts:407
if (
res.status === 422 &&
typeof errBody.detail === 'object' &&
errBody.detail?.code === 'missing_placeholders'
) {
throw new FeaturePromptsError(errBody.detail);
}
// FastAPI can return ``detail`` as a string or a structured object.
// Stringifying an object via the ``||`` shortcut yields "[object Object]";
// serialize explicitly.
let message: string;
if (typeof errBody.detail === 'string') {
message = errBody.detail;
} else if (errBody.detail) {
message = JSON.stringify(errBody.detail);
} else {
message = `Failed to update feature prompts (status ${res.status}).`;
}
throw new Error(message);
}
// Success path: require a valid JSON body. Swallowing parse errors here
// would let an invalid success response be returned as FeaturePrompts
// with undefined fields — caller code would then read .cover_letter_prompt
// and get surprising behavior. Let the parse error propagate.
return (await res.json()) as FeaturePrompts;
}
// API Key Management types
export type ApiKeyProvider =
| 'openai'
| 'azure_foundry'
| 'anthropic'
| 'google'
| 'openrouter'
| 'deepseek'
| 'groq'View on GitHub (pinned to 116f9cc3b0)
Solutions
- Inspect the thrown message: a string detail is the backend's own explanation; a JSON-stringified object contains structured validation info; the fallback text means inspect res.status via logs/network tab.
- 401/403 → re-authenticate; 404 → fix BACKEND_ORIGIN/next.config.ts rewrites; 5xx → check backend logs.
- For object details, parse the JSON in the message to locate the offending field and correct the FeaturePromptsUpdate payload.
- Wrap the `fresh` refresh/save flow in try/catch so the error is displayed in the form rather than crashing the settings page.
Example fix
// before
await updateFeaturePrompts(update);
// after
try {
await updateFeaturePrompts(update);
} catch (e) {
if (e instanceof FeaturePromptsError) {
showPlaceholderHints(e.detail);
} else {
showSaveError(e instanceof Error ? e.message : String(e));
}
} Defensive patterns
Strategy: try-catch
Validate before calling
function isNonEmptyPromptUpdate(u: FeaturePromptsUpdate): boolean {
return Object.values(u).every((v) => typeof v === 'string' && v.trim().length > 0);
} Type guard
function hasStringDetail(x: unknown): x is { detail: string } {
return typeof x === 'object' && x !== null && typeof (x as any).detail === 'string';
} Try / catch
try {
await updateFeaturePrompts(update);
} catch (e) {
if (e instanceof FeaturePromptsError) handlePlaceholders(e.detail);
else showError(e instanceof Error ? e.message : 'Unknown save failure');
} Prevention
- Catch FeaturePromptsError separately from the generic Error branch
- Inspect the network response body — the thrown message may embed JSON detail
- Re-authenticate before retrying after 401/403
- Keep frontend/backend versions aligned so the endpoint path exists
When it happens
Trigger: Non-ok response on POST/PUT /config/feature-prompts that isn't the 422 missing_placeholders case: 401/403 (session expired, CSRF), 422 with a different validation code, 404 (endpoint absent / proxy misroute), 500/502 (backend down or failed persisting prompts).
Common situations: Saving feature prompts after the auth cookie expired; deploying mismatched frontend/backend versions so the endpoint moved; infrastructure outage returning an HTML error page (res.json() catch yields {}, so the fallback text shows).
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}).
- Failed to load API key status (status ${res.status}).
- ${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/1bb8829b7f7beb23.
Report an issue: GitHub.