{"record":{"id":"41c8b3f1ce2ba94b","repo":"srbhr/Resume-Matcher","slug":"resume-has-no-processed-data","errorCode":null,"errorMessage":"Resume has no processed data.","messagePattern":"Resume has no processed data\\.","errorType":"http","errorClass":"HTTPException","httpStatus":400,"severity":"error","filePath":"apps/backend/app/routers/enrichment.py","lineNumber":186,"sourceCode":"            detail=\"Failed to analyze resume. Please try again.\",\n        )\n\n\n@router.post(\"/enhance\", response_model=EnhancementPreview)\nasync def generate_enhancements(request: EnhanceRequest) -> EnhancementPreview:\n    \"\"\"Generate enhanced descriptions from user answers.\n\n    Takes the answers to clarifying questions and uses AI to generate\n    improved description bullets for each item.\n    \"\"\"\n    # Fetch resume\n    resume = await db.get_resume(request.resume_id)\n    if not resume:\n        raise HTTPException(status_code=404, detail=\"Resume not found\")\n\n    processed_data = resume.get(\"processed_data\")\n    if not processed_data:\n        raise HTTPException(\n            status_code=400,\n            detail=\"Resume has no processed data.\",\n        )\n\n    # Group answers by item_id.\n    # When all answers carry item_id (from the analysis step), we can skip\n    # the expensive re-analysis LLM call and derive item details from the\n    # resume's processed_data directly.\n    answers_by_item: dict[str, list[AnswerInput]] = {}\n    item_details: dict[str, dict] = {}\n    # question_id → question dict, populated only in the legacy path\n    questions_by_id: dict[str, dict] = {}\n\n    if all(a.item_id for a in request.answers) and all(\n        _extract_item_from_resume(processed_data, a.item_id or \"\")\n        for a in request.answers\n    ):\n        # Fast path — no re-analysis needed","sourceCodeStart":168,"sourceCodeEnd":204,"githubUrl":"https://github.com/srbhr/Resume-Matcher/blob/116f9cc3b00e1ac91734a6c2679bf41ea64a0edc/apps/backend/app/routers/enrichment.py#L168-L204","documentation":"Raised by generate_enhancements in apps/backend/app/routers/enrichment.py when the resume exists but has no processed_data field. Enhancement generation builds its analysis prompt from processed_data, so a 400 is returned.","triggerScenarios":"Calling /enhance for a resume record whose processed_data is missing/empty — incomplete prior processing, legacy records, or DB manipulation that stripped the field.","commonSituations":"Legacy/migrated resume records lacking processed_data; an earlier analyze call failed and the pipeline never stored processed data; partial DB restores.","solutions":["Re-upload the resume to regenerate processed_data","Ensure the analyze step completed successfully before calling /enhance","Inspect the resume document in the DB to confirm which fields are missing","Migrate legacy records through the processing pipeline"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"const resume = await api.getResume(request.resumeId);\nif (!resume?.processed_data) throw new Error('Run analysis/re-upload first: no processed data');","typeGuard":"function hasProcessedData(r) { return r != null && r.processed_data != null && Object.keys(r.processed_data).length > 0; }","tryCatchPattern":"try { await api.enhance(req); } catch (e) { if (e.status === 400 && /processed data/.test(e.detail)) { await promptReupload(); } else throw e; }","preventionTips":["Enforce the analyze → enhance workflow order in the UI","Re-upload resumes missing processed_data instead of enhancing blind","Audit DB records after migrations for missing processed_data","Disable the enhance button until processed_data exists"],"tags":["http","validation","resume","data-integrity"],"backgroundTag":"missing-processed-data","analyzedSha":"116f9cc3b00e1ac91734a6c2679bf41ea64a0edc","analyzedAt":"2026-08-28T22:51:40.999Z","schemaVersion":2},"datasetVersion":"2026-08-29T02:17:18.158Z"}