{"record":{"id":"546c78870d7a4e75","repo":"srbhr/Resume-Matcher","slug":"resume-has-no-processed-data-please-re-upload-the-546c78","errorCode":null,"errorMessage":"Resume has no processed data. Please re-upload the resume.","messagePattern":"Resume has no processed data\\. Please re-upload the resume\\.","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"apps/backend/app/routers/resumes.py","lineNumber":1812,"sourceCode":"    if not improvement:\n        raise HTTPException(\n            status_code=400,\n            detail=\"No job context found for this resume. \"\n            \"The resume may have been created before job tracking was implemented.\",\n        )\n\n    # Get the job description\n    job = await db.get_job(improvement[\"job_id\"])\n    if not job:\n        raise HTTPException(\n            status_code=404,\n            detail=\"The associated job description was not found.\",\n        )\n\n    # Get resume data\n    resume_data = resume.get(\"processed_data\")\n    if not resume_data:\n        raise HTTPException(\n            status_code=400,\n            detail=\"Resume has no processed data. Please re-upload the resume.\",\n        )\n\n    # Get language setting\n    language = get_content_language()\n\n    # Generate cover letter\n    try:\n        cover_letter_content = await generate_cover_letter(\n            resume_data, job[\"content\"], language\n        )\n    except Exception as e:\n        logger.error(f\"Cover letter generation failed: {e}\")\n        raise HTTPException(\n            status_code=500,\n            detail=\"Failed to generate cover letter. Please try again.\",\n        )","sourceCodeStart":1794,"sourceCodeEnd":1830,"githubUrl":"https://github.com/srbhr/Resume-Matcher/blob/116f9cc3b00e1ac91734a6c2679bf41ea64a0edc/apps/backend/app/routers/resumes.py#L1794-L1830","documentation":"HTTP 400 raised by generate_cover_letter_endpoint when the tailored resume exists and its job context is valid, but the resume's 'processed_data' field (the structured parsed JSON of the resume) is empty or missing. Cover-letter generation builds its prompt from processed_data, so without it the request cannot proceed and the user is told to re-upload.","triggerScenarios":"Cover-letter generation requested for a resume whose processed_data is null/empty — e.g. initial AI parsing failed or was interrupted, a migration dropped the field, or the resume record was created without the parse step completing.","commonSituations":"Parsing pipeline crashed after the resume row was saved but before processed_data was written; legacy imports missing the field; manual DB edits or storage cleanup removed the parsed JSON.","solutions":["Re-upload the resume so it is re-parsed and processed_data is populated, then retry generation.","If the original content exists, trigger a re-parse/reprocess endpoint to regenerate processed_data instead of a full re-upload.","Check server logs for the original parse failure (quota, rate limits, malformed file) and fix the root cause first.","Backfill processed_data for affected legacy resumes via a batch re-parse script."],"exampleFix":"// before\nawait api.post(`/resumes/${resumeId}/generate-cover-letter`); // 400: no processed_data\n\n// after\nconst resume = await api.get(`/resumes/${resumeId}`);\nif (!resume.data.processed_data) {\n  await api.post(`/resumes/${resumeId}/reprocess`); // or re-upload the file\n}\nawait api.post(`/resumes/${resumeId}/generate-cover-letter`);","handlingStrategy":"validation","validationCode":"const resume = await api.get(`/resumes/${resumeId}`);\nif (!resume.data.processed_data) {\n  throw new Error('Resume has no processed data — re-upload or reprocess first.');\n}","typeGuard":"const hasProcessedData = (r) => r?.processed_data != null && typeof r.processed_data === 'object' && Object.keys(r.processed_data).length > 0;","tryCatchPattern":"try {\n  await api.post(`/resumes/${resumeId}/generate-cover-letter`);\n} catch (e) {\n  if (e.response?.status === 400 && /no processed data/.test(e.response.data?.detail ?? '')) {\n    notify('Re-parsing resume before generating the cover letter…');\n    await api.post(`/resumes/${resumeId}/reprocess`);\n    await api.post(`/resumes/${resumeId}/generate-cover-letter`);\n  } else throw e;\n}","preventionTips":["Only enable cover-letter generation after processed_data is confirmed non-empty.","Alert on parse jobs that save a resume row without writing processed_data.","Backfill legacy resumes missing processed_data via batch re-parse."],"tags":["http-400","missing-data","resume-parsing"],"backgroundTag":"missing-processed-data","analyzedSha":"116f9cc3b00e1ac91734a6c2679bf41ea64a0edc","analyzedAt":"2026-08-28T22:51:40.999Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}