srbhr/Resume-Matcher · error · HTTPException
Could not update the resume draft.
Error message
Could not update the resume draft.
What it means
A 422 raised by resume_wizard_turn when run_ai_turn raises ValueError, meaning the wizard state or answer text failed validation (e.g. invalid state transition, malformed answer for the current step). The underlying message is logged; clients get a generic draft-update failure.
Source
Thrown at apps/backend/app/routers/resume_wizard.py:60
return ResumeWizardTurnResponse(state=apply_review(request.state))
# Cost guard: once the question cap is reached, stop making LLM calls for
# answer/skip turns and route the user to review instead of advancing.
if request.state.asked_count >= RESUME_WIZARD_MAX_QUESTIONS:
return ResumeWizardTurnResponse(state=apply_review(request.state))
if action == "skip":
state = await run_ai_turn(request.state, "", skip=True)
return ResumeWizardTurnResponse(state=state)
answer_text = request.answer.text if request.answer else ""
state = await run_ai_turn(request.state, answer_text, skip=False)
return ResumeWizardTurnResponse(state=state)
except HTTPException:
raise
except ValueError as e:
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,View on GitHub (pinned to 116f9cc3b0)
Solutions
- Inspect server logs for 'Resume wizard turn validation failed' to see the exact ValueError
- Re-fetch the current wizard state and resubmit an answer valid for that step
- Validate the answer format client-side before sending (dates, enums, required fields)
- If the state is unrecoverable, restart the wizard session
Example fix
// before
await api.post('/resume-wizard/turn', { state, answer: rawInput });
// after
const parsed = stepSchema.safeParse(rawInput);
if (!parsed.success) showStepError(parsed.error);
else await api.post('/resume-wizard/turn', { state, answer: parsed.data }); Defensive patterns
Strategy: validation
Validate before calling
function validateWizardAnswer(step, answer) {
if (answer == null || String(answer).trim() === '') throw new ValidationError('Answer is required');
if (step.expectedType === 'date' && isNaN(Date.parse(answer))) throw new ValidationError('Invalid date');
if (step.expectedType === 'number' && isNaN(Number(answer))) throw new ValidationError('Expected a number');
} Type guard
function isWellFormedState(state) {
return state != null && typeof state === 'object' &&
typeof state.current_step === 'string' && state.resume_data != null;
} Try / catch
try {
await api.post('/resume-wizard/turn', { state, answer });
} catch (e) {
if (e.response?.status === 422) {
const fresh = await api.get('/resume-wizard/state'); // resync and let user re-answer
showStepRetry(fresh);
} else throw e;
} Prevention
- Re-fetch wizard state before each turn instead of trusting a local copy
- Validate answer format per step type before submitting
- Prevent out-of-order step submissions in the UI
- Surface the 422 as a 'please re-answer this step' prompt, not a crash
When it happens
Trigger: Answering a wizard step with text that doesn't parse into the expected field type; posting a turn against a stale/invalid wizard state; calling the turn endpoint out of order (skipping steps the state machine requires).
Common situations: Client replays an old answer after the wizard state advanced; frontend sends free text where a structured value (date, number) is expected; wizard state was reset server-side while the client kept its local copy.
Related errors
- No job descriptions provided
- Empty job description
- ${message = data.detail or Failed to update LLM config (stat
- ${data.detail || Failed to update feature config (status ${r
- ${data.detail || Failed to update language config (status ${
AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28).
Data as JSON: /api/errors/cddf67907ff2f7f0.
Report an issue: GitHub.