srbhr/Resume-Matcher · error · Error
${data.detail || Failed to generate enhancements (status ${r
Error message
${data.detail || Failed to generate enhancements (status ${res.status}).} What it means
generateEnhancements in apps/frontend/lib/api/enrichment.ts throws this Error when POSTing the user's answers to the enhancement-generation endpoint returns a non-OK response. Like its siblings, it prefers the server's JSON `detail` field and falls back to a status-embedded generic message. It signals the backend rejected or failed the enhancement generation step.
Source
Thrown at apps/frontend/lib/api/enrichment.ts:80
return res.json();
}
/**
* Generate enhanced descriptions from user answers.
*/
export async function generateEnhancements(
resumeId: string,
answers: AnswerInput[]
): Promise<EnhancementPreview> {
const res = await apiPost('/enrichment/enhance', {
resume_id: resumeId,
answers,
});
if (!res.ok) {
const data = await res.json().catch(() => ({}));
throw new Error(data.detail || `Failed to generate enhancements (status ${res.status}).`);
}
return res.json();
}
/**
* Apply enhancements to the master resume.
*/
export async function applyEnhancements(
resumeId: string,
enhancements: EnhancedDescription[]
): Promise<{ message: string; updated_items: number }> {
const res = await apiPost(`/enrichment/apply/${resumeId}`, {
enhancements,
});
if (!res.ok) {
const data = await res.json().catch(() => ({}));View on GitHub (pinned to 116f9cc3b0)
Solutions
- Read res.status and the JSON detail to pinpoint 401 vs 404 vs 422 vs 5xx.
- For 422: validate the answers payload matches the API schema (each answer has question id and non-empty text) before calling.
- For 401: redirect the user to re-login or refresh the session before retrying.
- For 429/5xx: retry with exponential backoff, and check backend AI provider config/quota.
- For 404: verify the resumeId exists; re-select the resume if it was deleted.
Example fix
// before
const res = await apiPost('/enrichment/generate', { resume_id: resumeId, answers });
if (!res.ok) {
const data = await res.json().catch(() => ({}));
throw new Error(data.detail || `Failed to generate enhancements (status ${res.status}).`);
}
// after
const res = await apiPost('/enrichment/generate', { resume_id: resumeId, answers });
if (!res.ok && res.status === 422) {
throw new Error('Some answers were invalid. Please review and resubmit.');
}
if (!res.ok) {
const data = await res.json().catch(() => ({}));
throw new Error(data.detail || `Failed to generate enhancements (status ${res.status}).`);
} Defensive patterns
Strategy: validation
Validate before calling
const valid = resumeId?.trim() && Array.isArray(answers) && answers.length > 0 && answers.every(a => a && a.question_id && typeof a.answer === 'string');
if (!valid) throw new Error('Invalid answers payload for enhancement generation.'); Type guard
function hasValidAnswers(a: unknown): a is AnswerInput[] {
return Array.isArray(a) && a.length > 0 && a.every(x =>
typeof x === 'object' && x !== null && 'question_id' in x && 'answer' in x);
} Try / catch
try {
const enhancements = await generateEnhancements(resumeId, answers);
} catch (e) {
const msg = e instanceof Error ? e.message : String(e);
if (msg.includes('status 401')) redirectToLogin();
else if (msg.includes('status 422')) showToast('Please review your answers and try again.');
else showToast('Could not generate enhancements. Please retry in a moment.');
} Prevention
- Validate the answers array against the AnswerInput shape before every call.
- Keep the frontend payload type in sync with the backend Pydantic schema; regenerate types on API changes.
- Add a retry path with backoff for transient 429/5xx statuses.
When it happens
Trigger: apiPost(`/enrichment/generate`, { resume_id: resumeId, answers }) resolves with a 4xx/5xx status: 401 unauthenticated, 404 unknown resume_id, 422 answers payload fails server-side validation (missing/malformed answers array), 429 AI rate limit, 500 when the LLM enhancement service errors.
Common situations: User submits wizard answers after their session cookie expired (401); the payload shape drifted from the backend Pydantic schema after an API change (422); the LLM provider times out or quota is exhausted (500/429); resumeId refers to a resume deleted earlier (404).
Related errors
- ${data.detail || Failed to analyze resume (status ${res.stat
- ${data.detail || Failed to apply enhancements (status ${res.
- ${data.detail || Failed to regenerate content (status ${res.
- ${data.detail || Failed to apply changes (status ${res.statu
- ${text || Resume wizard turn failed with status ${response.s
AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28).
Data as JSON: /api/errors/5cc343c2983a88d0.
Report an issue: GitHub.