srbhr/Resume-Matcher · error · HTTPException
Resume has no stored content to re-process.
Error message
Resume has no stored content to re-process.
What it means
HTTP 400 raised by retry_processing when the resume passes the status check but has an empty 'content' field — there is no stored markdown to feed back into parse_resume_to_json. Without the original markdown the AI re-parse cannot run, so the endpoint refuses rather than silently producing an empty result.
Source
Thrown at apps/backend/app/routers/resumes.py:1697
async def retry_processing(resume_id: str) -> ResumeUploadResponse:
"""Retry AI processing for a failed or stuck resume.
Re-runs parse_resume_to_json() on the stored markdown content.
Works for resumes with processing_status == "failed" or "processing".
"""
resume = await db.get_resume(resume_id)
if not resume:
raise HTTPException(status_code=404, detail="Resume not found")
if resume.get("processing_status") not in ("failed", "processing"):
raise HTTPException(
status_code=400,
detail="Only resumes with 'failed' or 'processing' status can be retried.",
)
markdown_content = resume.get("content", "")
if not markdown_content:
raise HTTPException(
status_code=400,
detail="Resume has no stored content to re-process.",
)
try:
processed_data = await parse_resume_to_json(markdown_content)
await db.update_resume(
resume_id,
{
"processed_data": processed_data,
"processing_status": "ready",
},
)
return ResumeUploadResponse(
message="Resume processing succeeded on retry",
request_id=str(uuid4()),
resume_id=resume_id,
processing_status="ready",View on GitHub (pinned to 116f9cc3b0)
Solutions
- Re-upload the resume file so content (markdown) is stored, then retry processing.
- Inspect the resume record (GET resume) to confirm 'content' is non-empty before retrying.
- Fix the upload path that created the resume row without persisting content.
- If content was lost in a migration, restore it from object storage / original file.
Example fix
// before
await api.post(`/resumes/${id}/retry`);
// after
const r = await api.get(`/resumes/${id}`);
if (!r.data.content) {
await reuploadResume(id, file); // restore stored markdown first
}
await api.post(`/resumes/${id}/retry`); Defensive patterns
Strategy: validation
Validate before calling
const resume = await api.get(`/resumes/${id}`);
if (!resume.data.content) {
throw new Error('Resume has no stored content; re-upload required before retry.');
} Type guard
const hasContent = (r) => typeof r?.content === 'string' && r.content.trim().length > 0;
Try / catch
try {
await api.post(`/resumes/${id}/retry`);
} catch (e) {
if (e.response?.status === 400 && /no stored content/.test(e.response.data?.detail ?? '')) {
await promptReupload(id);
} else throw e;
} Prevention
- Verify content persisted (non-empty) after upload before marking the resume ready.
- Alert on resumes whose content is null but a processing status is set.
- Keep the original file in object storage so content can be restored.
When it happens
Trigger: Calling the retry endpoint on a 'failed'/'processing' resume whose 'content' (markdown) column is null, missing, or an empty string — e.g. the record was created but content upload/persist failed before processing started.
Common situations: Partial DB write during initial upload (row created, content save failed); data migration that dropped the content column; manual DB cleanup removed content; resume imported from a legacy source without markdown stored.
Related errors
- Only resumes with 'failed' or 'processing' status can be ret
- No job context found for this resume. The resume may have be
- Resume has no processed data. Please re-upload the resume.
- Unsupported UI language: {request.ui_language}. Supported: {
- Unsupported content language: {request.content_language}. Su
AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28).
Data as JSON: /api/errors/21bad2fee3775e10.
Report an issue: GitHub.