srbhr/Resume-Matcher · error · Error

${text || Resume wizard turn failed with status ${response.s

Error message

${text || Resume wizard turn failed with status ${response.status}}

What it means

postResumeWizardTurn in apps/frontend/lib/api/resume-wizard.ts throws this Error when the POST to `/resume-wizard/turn` returns a non-OK response. Unlike the enrichment helpers it reads the raw response TEXT (not JSON detail), so the thrown message may contain an HTML error page or a JSON string. It signals the conversational resume-wizard backend rejected or failed the turn.

Source

Thrown at apps/frontend/lib/api/resume-wizard.ts:110

    step: 'intro',
    resume_data: emptyResumeData(),
    current_question: { text: INTRO_QUESTION, section: 'intro' },
    history: [],
    asked_count: 0,
    inferred_skills: [],
    is_complete: false,
    progress: { current: 0, total: 8 },
    warnings: [],
  };
}

export async function postResumeWizardTurn(
  payload: ResumeWizardTurnRequest
): Promise<ResumeWizardTurnResponse> {
  const response = await apiPost('/resume-wizard/turn', payload);
  if (!response.ok) {
    const text = await response.text().catch(() => '');
    throw new Error(text || `Resume wizard turn failed with status ${response.status}`);
  }
  return response.json();
}

export async function finalizeResumeWizard(
  state: ResumeWizardState
): Promise<ResumeWizardFinalizeResponse> {
  const response = await apiPost('/resume-wizard/finalize', { state });
  if (!response.ok) {
    const text = await response.text().catch(() => '');
    throw new Error(text || `Resume wizard finalize failed with status ${response.status}`);
  }
  return response.json();
}

View on GitHub (pinned to 116f9cc3b0)

Solutions

  1. Log response.status and the text body; if it looks like HTML, the failure is at a proxy/gateway, not the API itself.
  2. For 422, validate the ResumeWizardTurnRequest (state present, messages non-empty) before sending.
  3. For 401, re-authenticate and retry the turn.
  4. For 429/504, retry with backoff and check backend AI provider limits/timeout config.
  5. Prefer parsing JSON detail when content-type is JSON so users see a clean message instead of raw text/HTML.

Example fix

// before
const response = await apiPost('/resume-wizard/turn', payload);
if (!response.ok) {
  const text = await response.text().catch(() => '');
  throw new Error(text || `Resume wizard turn failed with status ${response.status}`);
}
// after
const response = await apiPost('/resume-wizard/turn', payload);
if (!response.ok) {
  const text = await response.text().catch(() => '');
  let detail = '';
  try { detail = JSON.parse(text)?.detail ?? ''; } catch { /* non-JSON */ }
  throw new Error(detail || `Resume wizard turn failed with status ${response.status}`);
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (!payload?.state) throw new Error('Resume wizard turn requires a state object.');

Type guard

function isWizardTurnRequest(p: unknown): p is ResumeWizardTurnRequest {
  return typeof p === 'object' && p !== null && 'state' in p;
}

Try / catch

try {
  const turn = await postResumeWizardTurn(payload);
} catch (e) {
  const msg = e instanceof Error ? e.message : '';
  if (/<html|<!doctype/i.test(msg)) showError('Service temporarily unavailable. Please retry.');
  else if (msg.includes('status 401')) redirectToLogin();
  else showError('The assistant could not process your reply. Please try again.');
}

Prevention

When it happens

Trigger: apiPost('/resume-wizard/turn', payload) resolves with response.ok === false: 401 expired session, 404 unknown wizard/resume state id, 422 payload fails schema validation (missing state, malformed messages), 429 AI rate limit, or 500/504 from the LLM turn processing.

Common situations: A gateway returns an HTML 502 page, so the user sees raw HTML inside the Error message; the wizard state was built by an older frontend version and no longer matches the schema (422); session cookie expired mid-conversation (401); LLM latency causes a gateway timeout (504).

Related errors


AI-assisted analysis of srbhr/Resume-Matcher@116f9cc3b0 (2026-08-28). Data as JSON: /api/errors/1f1a5c41e9020cc2. Report an issue: GitHub.