srbhr/Resume-Matcher · error · Error
Failed to fetch job description (status ${res.status}): ${te
Error message
Failed to fetch job description (status ${res.status}): ${text} What it means
fetchJobDescription issues GET /resumes/{id}/job-description and throws this Error on any non-OK status, embedding the response body text. It converts an HTTP failure retrieving the stored job description into an exception for the caller.
Source
Thrown at apps/frontend/lib/api/resume.ts:392
/** Retries AI processing for a failed resume */
export async function retryProcessing(resumeId: string): Promise<ResumeUploadResponse> {
const res = await apiPost(`/resumes/${encodeURIComponent(resumeId)}/retry-processing`, {});
if (!res.ok) {
const text = await res.text().catch(() => '');
throw new Error(`Failed to retry processing (status ${res.status}): ${text}`);
}
return res.json();
}
/** Fetches the job description used to tailor a resume */
export async function fetchJobDescription(
resumeId: string
): Promise<{ job_id: string; content: string }> {
const res = await apiFetch(`/resumes/${encodeURIComponent(resumeId)}/job-description`);
if (!res.ok) {
const text = await res.text().catch(() => '');
throw new Error(`Failed to fetch job description (status ${res.status}): ${text}`);
}
return res.json();
}
View on GitHub (pinned to 116f9cc3b0)
Solutions
- Check the status: 404 usually means no job description exists for that resume
- Verify the resume was created through the tailoring flow that stores the job description
- Re-authenticate for 401/403
- Check backend storage/DB health for 500 responses
- Handle the null/absent case in the UI instead of assuming a description always exists
Example fix
// before
const jd = await fetchJobDescription(resumeId);
// after
try {
const jd = await fetchJobDescription(resumeId);
} catch (e) {
setJdError('No job description available for this resume.');
} Defensive patterns
Strategy: try-catch
Validate before calling
if (!resumeId) throw new Error('resumeId is required');
// Optional readiness check
const exists = await resumeExists(resumeId);
if (!exists) throw new Error(`Resume ${resumeId} not found; cannot fetch job description`); Type guard
function hasJobDescription(v: unknown): v is { job_id: string; content: string } {
return (
typeof v === 'object' && v !== null &&
typeof (v as { job_id?: unknown }).job_id === 'string' &&
typeof (v as { content?: unknown }).content === 'string' &&
(v as { content: string }).content.length > 0
);
} Try / catch
try {
const jd = await fetchJobDescription(resumeId);
setJobDescription(jd.content);
} catch (e) {
if (e instanceof Error && /status 404/.test(e.message)) {
setJobDescription(null); // no description stored; render empty state
} else {
showError('Could not load the job description.');
}
} Prevention
- Treat a missing job description (404) as an expected empty state, not a crash
- Re-authenticate before retrying after 401
- Validate resumeId origin (never use stale/hardcoded ids)
- Keep resume records and their stored job descriptions in sync on deletion
- Log the full error message server-side for diagnosis
When it happens
Trigger: Non-2xx from the job-description endpoint: resume not found (404), no job description was ever attached to the resume (404/400), auth expired (401), or backend storage/DB read failure (500).
Common situations: Developers hit this when viewing a tailored resume whose original job description was not saved or was purged, when the resumeId comes from a stale link, or after the session cookie/JWT expired.
Related errors
- Failed to generate outreach message (status ${res.status}):
- Failed to generate interview preparation (status ${res.statu
- Failed to retry processing (status ${res.status}): ${text}
- ${fallback} (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/e6ae7d6b37698f56.
Report an issue: GitHub.