srbhr/Resume-Matcher · error · Error
Failed to download resume (status ${res.status}): ${text}
Error message
Failed to download resume (status ${res.status}): ${text} What it means
downloadResumePdf fetches a generated PDF blob for a resume via GET on the URL built by getResumePdfUrl (resume id, optional render settings and locale). If the response is not OK it captures the body text and throws this Error with the status and server detail; the caller's blob() then never receives data. It indicates PDF generation/download failed server-side.
Source
Thrown at apps/frontend/lib/api/resume.ts:271
params.set('pageSize', 'A4');
}
if (locale) {
params.set('lang', locale);
}
return `${API_BASE}/resumes/${encodeURIComponent(normalizedId)}/pdf?${params.toString()}`;
}
export async function downloadResumePdf(
resumeId: string,
settings?: TemplateSettings,
locale?: Locale
): Promise<Blob> {
const url = getResumePdfUrl(resumeId, settings, locale);
const res = await apiFetch(url);
if (!res.ok) {
const text = await res.text().catch(() => '');
throw new Error(`Failed to download resume (status ${res.status}): ${text}`);
}
return await res.blob();
}
/** Deletes a resume by ID */
export async function deleteResume(resumeId: string): Promise<void> {
const res = await apiDelete(`/resumes/${encodeURIComponent(resumeId)}`);
if (!res.ok) {
const text = await res.text().catch(() => '');
throw new Error(`Failed to delete resume (status ${res.status}): ${text}`);
}
}
/** Updates the cover letter for a resume */
export async function updateCoverLetter(resumeId: string, content: string): Promise<void> {
const res = await apiPatch(`/resumes/${encodeURIComponent(resumeId)}/cover-letter`, { content });
if (!res.ok) {
const text = await res.text().catch(() => '');View on GitHub (pinned to 116f9cc3b0)
Solutions
- Inspect status + body text in the message; a 500 usually requires checking backend PDF-render logs for the failing resume content.
- Validate the settings/locale values passed to getResumePdfUrl against what the backend supports (400/422).
- Confirm the resume still exists before attempting download (404) and refresh the resume list.
- Catch the error in the UI, show a download-failed toast, and offer a retry of the PDF fetch.
Example fix
// before
const blob = await downloadResumePdf(resumeId, settings, locale);
// after
let blob: Blob;
try {
blob = await downloadResumePdf(resumeId, settings, locale);
} catch (e) {
console.error('PDF download failed:', (e as Error).message);
notifyUser('Could not download PDF — please retry.');
return;
} Defensive patterns
Strategy: try-catch
Validate before calling
const list = await fetchResumeList(false);
if (!list.some((r) => r.id === resumeId)) {
throw new Error(`Resume ${resumeId} not found; skip PDF download`);
} Type guard
function isBlob(x: unknown): x is Blob {
return typeof Blob !== 'undefined' && x instanceof Blob;
} Try / catch
try {
const blob = await downloadResumePdf(resumeId, settings, locale);
} catch (e) {
if ((e as Error).message.includes('status 5')) {
notifyUser('PDF generation failed on the server; try again later.');
} else {
notifyUser('Download failed: ' + (e as Error).message);
}
} Prevention
- Only offer PDF download for locales/settings known to be supported by the backend.
- Verify the resume exists (list fetch) before building the download URL.
- Offer a retry button — transient 500s from the renderer are common.
- Keep auth fresh for long builder sessions so the download request is not rejected with 401.
When it happens
Trigger: apiFetch(getResumePdfUrl(resumeId, settings, locale)) returns non-2xx: PDF render job failure on the backend (500), invalid settings/locale producing a 400, unknown resumeId (404), or auth rejection (401/403). Malformed query params for settings can also trigger a 422.
Common situations: Downloading a PDF for a resume whose content contains data the renderer cannot handle (500); passing a locale code the backend does not support; bookmarked/download URL reuse after the resume was deleted; expired session during a long builder session.
Understand the failure class
Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.
Related errors
- Failed to load resume (status ${res.status}).
- Failed to load resumes list (status ${res.status}).
- Failed to update resume (status ${res.status}): ${text}
- Failed to delete resume (status ${res.status}): ${text}
- Failed to download cover letter (status ${res.status}): ${te
AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28).
Data as JSON: /api/errors/7a24cea10650bf4e.
Report an issue: GitHub.