srbhr/Resume-Matcher · error · Error
${data.detail || Failed to analyze resume (status ${res.stat
Error message
${data.detail || Failed to analyze resume (status ${res.status}).} What it means
analyzeResume in apps/frontend/lib/api/enrichment.ts throws this Error when the POST to the backend resume-analysis endpoint returns a non-OK HTTP response. It first tries to read the JSON body and surface the server-provided `detail` message (FastAPI-style error payloads); if the body is not valid JSON, it falls back to a generic message embedding the HTTP status code. This is a client-side wrapper around any 4xx/5xx backend response during AI resume analysis.
Source
Thrown at apps/frontend/lib/api/enrichment.ts:60
}
export interface EnhancementPreview {
enhancements: EnhancedDescription[];
}
/**
* Analyze a resume to identify items that need enrichment.
* Returns items with weak descriptions and clarifying questions.
*/
export async function analyzeResume(resumeId: string): Promise<AnalysisResponse> {
const res = await apiFetch(`/enrichment/analyze/${resumeId}`, {
method: 'POST',
credentials: 'include',
});
if (!res.ok) {
const data = await res.json().catch(() => ({}));
throw new Error(data.detail || `Failed to analyze resume (status ${res.status}).`);
}
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) {View on GitHub (pinned to 116f9cc3b0)
Solutions
- Log or inspect res.status and the response body to identify whether it is 401/404/429/5xx before changing code.
- If 401: re-authenticate the user / refresh the session cookie before calling analyzeResume (credentials: 'include' only sends cookies that exist).
- If 404: verify the resumeId is valid and still exists (fetch the resume list first); do not analyze a deleted resume.
- If 5xx: check backend logs for the analysis/AI-provider failure (API keys, quota, timeout) and add a retry with backoff for transient 502/503/429.
- Confirm NEXT_PUBLIC_API_BASE_URL / proxy config points at the running backend so the route resolves.
Example fix
// before
const res = await fetch(`${API_URL}/enrichment/analyze/${resumeId}`, { method: 'POST', credentials: 'include' });
if (!res.ok) {
const data = await res.json().catch(() => ({}));
throw new Error(data.detail || `Failed to analyze resume (status ${res.status}).`);
}
// after
const res = await fetch(`${API_URL}/enrichment/analyze/${resumeId}`, { method: 'POST', credentials: 'include' });
if (res.status === 401) throw new Error('Your session expired. Please sign in again.');
if (!res.ok) {
const data = await res.json().catch(() => ({}));
throw new Error(data.detail || `Failed to analyze resume (status ${res.status}).`);
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!resumeId || !resumeId.trim()) throw new Error('A valid resumeId is required before analyzing.'); Type guard
function isAnalysisError(e: unknown): e is Error & { status?: number } {
return e instanceof Error && e.message.includes('Failed to analyze resume');
} Try / catch
try {
const analysis = await analyzeResume(resumeId);
} catch (e) {
if (isAnalysisError(e) && /status 401/.test(e.message)) {
redirectToLogin();
} else {
showToast(e instanceof Error ? e.message : 'Analysis failed. Please try again.');
}
} Prevention
- Always call analyzeResume with a resumeId verified to exist (from the resume list) rather than cached state.
- Handle session expiry centrally (e.g. a fetch wrapper that redirects on 401) so analyze errors degrade gracefully.
- Log res.status and the detail body in dev to distinguish auth vs validation vs server failures quickly.
When it happens
Trigger: The `fetch` POST (with credentials: 'include') resolves with res.ok === false: e.g. 401 when the auth cookie is missing/expired, 404 when resumeId does not exist server-side, 422 when the resumeId format is invalid, 429 rate limiting on the AI analysis backend, or 500/502/503 when the AI analysis service fails or times out.
Common situations: User session expired so cookies are no longer valid (401); the resume was deleted in another tab so the ID is stale (404); the backend LLM provider key is missing/out of quota causing 500; the frontend is pointed at the wrong API base URL so the route 404s; a proxy/gateway returns an HTML error page so res.json() fails and the fallback message appears.
Related errors
- ${data.detail || Failed to generate enhancements (status ${r
- ${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/db6032cbaed51146.
Report an issue: GitHub.