{"record":{"id":"0aa95bdc9d5ca2e1","repo":"srbhr/Resume-Matcher","slug":"upload-failed-with-status-res-status","errorCode":null,"errorMessage":"Upload failed with status ${res.status}","messagePattern":"Upload failed with status (.+?)","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"apps/frontend/lib/api/resume.ts","lineNumber":154,"sourceCode":"\n  try {\n    return JSON.parse(text) as ImprovedResult;\n  } catch (parseError) {\n    console.error('Failed to parse improve response:', parseError, 'Raw response:', text);\n    throw parseError;\n  }\n}\n\n/** Uploads job descriptions and returns a job_id */\nexport async function uploadJobDescriptions(\n  descriptions: string[],\n  resumeId: string\n): Promise<string> {\n  const res = await apiPost('/jobs/upload', {\n    job_descriptions: descriptions,\n    resume_id: resumeId,\n  });\n  if (!res.ok) throw new Error(`Upload failed with status ${res.status}`);\n  const data = await res.json();\n  return data.job_id[0];\n}\n\n/** Improves the resume and returns the full preview object */\nexport async function improveResume(\n  resumeId: string,\n  jobId: string,\n  promptId?: string\n): Promise<ImprovedResult> {\n  return postImprove('/resumes/improve', {\n    resume_id: resumeId,\n    job_id: jobId,\n    prompt_id: promptId ?? null,\n  });\n}\n\n/** Previews the resume improvement without saving */","sourceCodeStart":136,"sourceCodeEnd":172,"githubUrl":"https://github.com/srbhr/Resume-Matcher/blob/116f9cc3b00e1ac91734a6c2679bf41ea64a0edc/apps/frontend/lib/api/resume.ts#L136-L172","documentation":"uploadJobDescriptions in apps/frontend/lib/api/resume.ts throws this terse Error when the POST to `/jobs/upload` returns a non-OK status, including only the numeric status code (no response body). It indicates the backend rejected the batch of job descriptions or failed while creating the job record; diagnosing requires inspecting the network tab or backend logs since the message omits details.","triggerScenarios":"apiPost('/jobs/upload', { job_descriptions: descriptions, resume_id: resumeId }) resolves with res.ok === false: 401 unauthenticated, 404 resume_id not found, 422 empty descriptions array or items exceeding size/count limits, 413 payload too large, or 5xx backend storage/processing failure.","commonSituations":"Pasting very large or many job descriptions exceeds the request body limit (413); descriptions array is empty because scraping/parsing yielded nothing (422); resumeId references a deleted resume (404); auth cookie expired (401).","solutions":["Reproduce in the browser network tab to read the response body, since this message omits it; classify 401/404/413/422/5xx.","Validate before calling: descriptions is a non-empty array of non-empty strings and resumeId is a non-empty ID.","For 413, chunk the upload into smaller batches or raise the backend body-size limit.","For 401, re-authenticate and retry; for 404, verify the resume exists.","For 5xx, check backend logs for job-creation/storage errors."],"exampleFix":"// before\nconst res = await apiPost('/jobs/upload', {\n  job_descriptions: descriptions,\n  resume_id: resumeId,\n});\nif (!res.ok) throw new Error(`Upload failed with status ${res.status}`);\n// after\nif (!Array.isArray(descriptions) || descriptions.length === 0) {\n  throw new Error('Provide at least one job description to upload.');\n}\nconst res = await apiPost('/jobs/upload', {\n  job_descriptions: descriptions,\n  resume_id: resumeId,\n});\nif (!res.ok) {\n  const data = await res.json().catch(() => ({}));\n  throw new Error(data.detail || `Upload failed with status ${res.status}`);\n}","handlingStrategy":"validation","validationCode":"const cleaned = (descriptions ?? []).map(d => (d ?? '').trim()).filter(Boolean);\nif (cleaned.length === 0) throw new Error('Provide at least one non-empty job description.');\nif (!resumeId?.trim()) throw new Error('resumeId is required to upload job descriptions.');","typeGuard":"function hasUploadableDescriptions(v: unknown): v is string[] {\n  return Array.isArray(v) && v.length > 0 &&\n    v.every(d => typeof d === 'string' && d.trim().length > 0);\n}","tryCatchPattern":"try {\n  const jobId = await uploadJobDescriptions(descriptions, resumeId);\n} catch (e) {\n  const msg = e instanceof Error ? e.message : '';\n  if (msg.includes('status 413')) showError('Too much content — upload fewer or shorter descriptions.');\n  else if (msg.includes('status 401')) redirectToLogin();\n  else showError('Upload failed. Please retry.');\n}","preventionTips":["Filter empty/whitespace descriptions and cap batch size client-side to avoid 422/413.","Since this error message omits the body, check the network tab (or improve the helper to read detail) for diagnosis.","Verify the target resume exists before uploading jobs against it."],"tags":["http-error","fetch","upload","api-client"],"backgroundTag":"http-non-ok-response","analyzedSha":"116f9cc3b00e1ac91734a6c2679bf41ea64a0edc","analyzedAt":"2026-08-28T22:51:40.999Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}