srbhr/Resume-Matcher · error · HTTPException
No job context found for this resume. The resume may have be
Error message
No job context found for this resume. The resume may have been created before job tracking was implemented.
What it means
HTTP 400 raised by generate_cover_letter_endpoint when the resume is tailored (has parent_id) but no improvement record exists in the improvements table linking that tailored resume to a job (db.get_improvement_by_tailored_resume returns None). Without that link the endpoint cannot determine which job description to base the letter on.
Source
Thrown at apps/backend/app/routers/resumes.py:1795
- The resume must have an associated job context in the improvements table
"""
# Get the resume
resume = await db.get_resume(resume_id)
if not resume:
raise HTTPException(status_code=404, detail="Resume not found")
# Check if it's a tailored resume (has parent_id)
if not resume.get("parent_id"):
raise HTTPException(
status_code=400,
detail="Cover letter can only be generated for tailored resumes. "
"Please tailor this resume to a job description first.",
)
# Get improvement record to find the job_id
improvement = await db.get_improvement_by_tailored_resume(resume_id)
if not improvement:
raise HTTPException(
status_code=400,
detail="No job context found for this resume. "
"The resume may have been created before job tracking was implemented.",
)
# Get the job description
job = await db.get_job(improvement["job_id"])
if not job:
raise HTTPException(
status_code=404,
detail="The associated job description was not found.",
)
# Get resume data
resume_data = resume.get("processed_data")
if not resume_data:
raise HTTPException(
status_code=400,View on GitHub (pinned to 116f9cc3b0)
Solutions
- Re-tailor the resume against the target job so a fresh improvement record linking resume to job_id is created.
- If the job is known, insert/backfill the missing improvement record (resume_id + job_id) via a data-fix script.
- Audit legacy tailored resumes lacking improvement rows and re-run tailoring for them.
- Make the tailor flow transactional so the resume and improvement record are written together.
Example fix
// before
await api.post(`/resumes/${resumeId}/generate-cover-letter`); // 400 if no improvement
// after: ensure linkage exists by re-tailoring
const resume = await api.get(`/resumes/${resumeId}`);
if (!resume.data.parent_id || !(await hasImprovement(resumeId))) {
const re = await api.post(`/resumes/${resumeId}/retailor`, { jobId });
resumeId = re.data.id;
}
await api.post(`/resumes/${resumeId}/generate-cover-letter`); Defensive patterns
Strategy: validation
Validate before calling
const resume = await api.get(`/resumes/${resumeId}`);
if (!resume.data.parent_id) throw new Error('Not a tailored resume');
// ensure the job linkage (improvement) exists
const improvements = await api.get(`/improvements?tailoredResumeId=${resumeId}`);
if (!improvements.data.length) throw new Error('No job context; re-tailor the resume.'); Type guard
const hasJobContext = (r, improvements) => Boolean(r?.parent_id) && improvements.some((i) => i.tailored_resume_id === r.id && i.job_id);
Try / catch
try {
await api.post(`/resumes/${resumeId}/generate-cover-letter`);
} catch (e) {
if (e.response?.status === 400 && /job context/.test(e.response.data?.detail ?? '')) {
notify('Job context missing — re-tailoring the resume.');
await api.post(`/resumes/${resumeId}/retailor`, { jobId });
} else throw e;
} Prevention
- Run a data audit for tailored resumes lacking improvement rows and re-tailor them.
- Make tailoring write the resume and improvement record atomically.
- Verify job_id linkage after any DB migration affecting improvements.
When it happens
Trigger: Cover-letter generation requested for a tailored resume that has no corresponding row in the improvements table — typically records created before job tracking was implemented, an interrupted tailoring run, or an improvement row deleted manually.
Common situations: Legacy data migrated from a pre-job-tracking schema; tailoring job crashed after creating the child resume but before writing the improvement record; DB cleanup scripts removed improvement rows but kept resumes.
Related errors
- Resume has no stored content to re-process.
- Resume has no processed data. Please re-upload the resume.
- Unsupported UI language: {request.ui_language}. Supported: {
- Unsupported content language: {request.content_language}. Su
- Unsupported prompt id: {request.default_prompt_id}. Supporte
AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28).
Data as JSON: /api/errors/50a17b0653e562ad.
Report an issue: GitHub.