{"record":{"id":"3ab15e5259ae3d14","repo":"srbhr/Resume-Matcher","slug":"failed-to-rename-resume-status-res-status","errorCode":null,"errorMessage":"Failed to rename resume (status ${res.status}): ${text}","messagePattern":"Failed to rename resume \\(status (.+?)\\): (.+?)","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/frontend/lib/api/resume.ts","lineNumber":310,"sourceCode":"}\n\n/** Updates the outreach message for a resume */\nexport async function updateOutreachMessage(resumeId: string, content: string): Promise<void> {\n  const res = await apiPatch(`/resumes/${encodeURIComponent(resumeId)}/outreach-message`, {\n    content,\n  });\n  if (!res.ok) {\n    const text = await res.text().catch(() => '');\n    throw new Error(`Failed to update outreach message (status ${res.status}): ${text}`);\n  }\n}\n\n/** Renames a resume by updating its title */\nexport async function renameResume(resumeId: string, title: string): Promise<void> {\n  const res = await apiPatch(`/resumes/${encodeURIComponent(resumeId)}/title`, { title });\n  if (!res.ok) {\n    const text = await res.text().catch(() => '');\n    throw new Error(`Failed to rename resume (status ${res.status}): ${text}`);\n  }\n}\n\n/** Downloads cover letter as PDF */\nexport function getCoverLetterPdfUrl(\n  resumeId: string,\n  pageSize: 'A4' | 'LETTER' = 'A4',\n  locale?: Locale\n): string {\n  const normalizedId = normalizeResumeId(resumeId);\n  const params = new URLSearchParams({ pageSize });\n  if (locale) {\n    params.set('lang', locale);\n  }\n  return `${API_BASE}/resumes/${encodeURIComponent(normalizedId)}/cover-letter/pdf?${params.toString()}`;\n}\n\nexport async function downloadCoverLetterPdf(","sourceCodeStart":292,"sourceCodeEnd":328,"githubUrl":"https://github.com/srbhr/Resume-Matcher/blob/116f9cc3b00e1ac91734a6c2679bf41ea64a0edc/apps/frontend/lib/api/resume.ts#L292-L328","documentation":"renameResume() PATCHes /resumes/:id/title via apiPatch. Any non-OK HTTP response causes this throw with status and body text included in the message. It is thrown for every failed title update, whether auth-, validation-, or server-related.","triggerScenarios":"Calling renameResume(resumeId, title) when the API returns !res.ok: unknown/deleted resumeId (404), expired session (401), empty or oversized title rejected (400/422), or backend error persisting the title (500).","commonSituations":"User submits an empty title from the inline editor (400); resume was deleted concurrently so the rename 404s; auth cookie/token expired (401); unique-constraint or DB failure on the backend (500).","solutions":["Parse the status/body from the message to determine the failure class.","If 400/422: validate the title client-side (non-empty, within length limit) and retry.","If 401: refresh the session and re-attempt the rename.","If 404: verify the resume still exists before renaming.","If 5xx: retry with backoff; check backend logs if repeated.","Revert the UI title to the previous value on failure so state stays consistent."],"exampleFix":"// before\nawait renameResume(resumeId, title);\n\n// after\nconst trimmed = title.trim();\nif (!trimmed || trimmed.length > 200) {\n  notifyUser('Title must be 1-200 characters.');\n  return;\n}\ntry {\n  await renameResume(resumeId, trimmed);\n} catch (err) {\n  setTitle(previousTitle);\n  notifyUser(`Rename failed: ${err.message}`);\n}","handlingStrategy":"try-catch","validationCode":"const trimmed = title.trim();\nif (!trimmed || trimmed.length > 200) {\n  throw new Error('Title must be between 1 and 200 characters');\n}","typeGuard":null,"tryCatchPattern":"try {\n  await renameResume(resumeId, trimmedTitle);\n} catch (err) {\n  const msg = err instanceof Error ? err.message : String(err);\n  setTitle(previousTitle); // rollback optimistic UI\n  notifyUser(msg.includes('status 404') ? 'Resume no longer exists' : `Rename failed: ${msg}`);\n}","preventionTips":["Validate the title (non-empty, length) before submitting.","Avoid optimistic UI updates, or always roll back on failure.","Check the resume still exists (or handle 404) before renaming.","Route all PATCH failures through a shared error handler that maps status codes to user messages."],"tags":["http","api","frontend","resume"],"backgroundTag":"http-non-ok-response","analyzedSha":"116f9cc3b00e1ac91734a6c2679bf41ea64a0edc","analyzedAt":"2026-08-28T22:51:40.999Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}