srbhr/Resume-Matcher · error · HTTPException
A master resume already exists. Delete it before creating a
Error message
A master resume already exists. Delete it before creating a new one.
What it means
A 409 raised at the start of finalize_resume_wizard when db.get_master_resume() returns an existing resume already marked processing_status 'ready'. Only one master resume may exist; finalize is refused until it is deleted.
Source
Thrown at apps/backend/app/routers/resume_wizard.py:77
logger.error("Resume wizard turn validation failed: %s", e)
raise HTTPException(status_code=422, detail="Could not update the resume draft.")
except Exception as e:
logger.error("Resume wizard turn failed: %s", e)
raise HTTPException(
status_code=500,
detail="Resume wizard failed. Please try again.",
)
@router.post("/finalize", response_model=ResumeWizardFinalizeResponse)
async def finalize_resume_wizard(
request: ResumeWizardFinalizeRequest,
) -> ResumeWizardFinalizeResponse:
"""Create the master resume from a validated wizard draft."""
try:
current_master = await db.get_master_resume()
if current_master and current_master.get("processing_status") == "ready":
raise HTTPException(
status_code=409,
detail="A master resume already exists. Delete it before creating a new one.",
)
normalized = normalize_resume_data(
request.state.resume_data.model_dump(mode="json")
)
data = ResumeData.model_validate(normalized).model_dump(mode="json")
content = json.dumps(data, ensure_ascii=False, sort_keys=True)
name = data.get("personalInfo", {}).get("name", "").strip() or "Resume"
title = f"{name} Master Resume"
# Set the title in the atomic create so a separate update can't fail and
# leave a committed-but-untitled master behind (which would 409 on retry).
resume = await db.create_resume_atomic_master(
content=content,
content_type="json",
filename=f"AI Resume Wizard - {name}.json",
processed_data=data,View on GitHub (pinned to 116f9cc3b0)
Solutions
- Delete the existing master resume via the resume deletion endpoint, then re-run finalize
- Fetch the master resume first and skip the wizard if one already exists (redirect user to it)
- For tests/dev, clear the master resume in setup/teardown before finalizing
- Serialize finalize calls in the client so only one runs at a time
Example fix
// before
await api.post('/resume-wizard/finalize', { state });
// after
const master = await api.get('/resumes/master');
if (master?.processing_status === 'ready') {
showToast('Master resume already exists');
} else {
await api.post('/resume-wizard/finalize', { state });
} Defensive patterns
Strategy: validation
Validate before calling
async function canFinalizeWizard(state) {
const master = await api.get('/resumes/master').catch(e => e.response?.status === 404 ? null : Promise.reject(e));
if (master && master.processing_status === 'ready') {
throw new ConflictError('Master resume already exists — delete it or reuse it');
}
return true;
} Type guard
function hasReadyMaster(r) {
return r != null && r.processing_status === 'ready';
} Try / catch
try {
await api.post('/resume-wizard/finalize', { state });
} catch (e) {
if (e.response?.status === 409) {
navigate('/resumes/master'); // existing master wins
} else throw e;
} Prevention
- Check for an existing ready master before starting the wizard
- Delete the old master resume before re-running finalize
- Serialize finalize calls; disable the button after first click
- Clean master resumes in test setup/teardown
When it happens
Trigger: Calling POST /resume-wizard/finalize when a ready master resume already exists; concurrent finalize calls after one succeeded; environment seeded with a master resume from a previous session.
Common situations: User finishes the wizard a second time without deleting the first master resume; two browser tabs finalize simultaneously; test/dev database reused across runs without cleanup.
Related errors
- Resume content changed or could not be uniquely matched. Ple
- Failed to save changes. Please try again.
- No job descriptions provided
- Empty job description
- Job not found
AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28).
Data as JSON: /api/errors/17bcde47865d41ef.
Report an issue: GitHub.