srbhr/Resume-Matcher · error · Error

Failed to retry processing (status ${res.status}): ${text}

Error message

Failed to retry processing (status ${res.status}): ${text}

What it means

retryProcessing calls POST /resumes/{id}/retry-processing to re-run AI processing for a failed resume, and throws this Error on any non-OK status. The response body text is appended to the message so the backend's failure detail is visible to the caller.

Source

Thrown at apps/frontend/lib/api/resume.ts:380

}

/** Generates interview preparation on-demand for a tailored resume */
export async function generateInterviewPrep(resumeId: string): Promise<InterviewPrepData> {
  const res = await apiPost(`/resumes/${encodeURIComponent(resumeId)}/generate-interview-prep`, {});
  if (!res.ok) {
    const text = await res.text().catch(() => '');
    throw new Error(`Failed to generate interview preparation (status ${res.status}): ${text}`);
  }
  const data = (await res.json()) as { interview_prep: InterviewPrepData };
  return data.interview_prep;
}

/** Retries AI processing for a failed resume */
export async function retryProcessing(resumeId: string): Promise<ResumeUploadResponse> {
  const res = await apiPost(`/resumes/${encodeURIComponent(resumeId)}/retry-processing`, {});
  if (!res.ok) {
    const text = await res.text().catch(() => '');
    throw new Error(`Failed to retry processing (status ${res.status}): ${text}`);
  }
  return res.json();
}

/** Fetches the job description used to tailor a resume */
export async function fetchJobDescription(
  resumeId: string
): Promise<{ job_id: string; content: string }> {
  const res = await apiFetch(`/resumes/${encodeURIComponent(resumeId)}/job-description`);
  if (!res.ok) {
    const text = await res.text().catch(() => '');
    throw new Error(`Failed to fetch job description (status ${res.status}): ${text}`);
  }
  return res.json();
}

View on GitHub (pinned to 116f9cc3b0)

Solutions

  1. Check status/text in the message for the server reason
  2. Confirm the resume is actually in a 'failed' state and still exists before retrying
  3. Re-authenticate for 401/403 responses
  4. If the retry succeeds but processing fails again, inspect backend AI provider configuration/credentials/quota
  5. Surface the server text to the end user so they know whether retrying again will help

Example fix

// before
await retryProcessing(resumeId);
// after
try {
  await retryProcessing(resumeId);
} catch (e) {
  showError('Retry failed: ' + e.message + '. If the problem persists, contact support.');
}
Defensive patterns

Strategy: retry

Validate before calling

const status = await getResumeStatus(resumeId);
if (status.state !== 'failed') {
  throw new Error(`Retry only applies to failed resumes (state: ${status.state})`);
}
if (!resumeId) throw new Error('resumeId is required');

Type guard

function isRetryableFailure(e: unknown): boolean {
  return e instanceof Error && /status 5\d\d/.test(e.message);
}

Try / catch

async function retryWithBackoff(resumeId: string, attempts = 3): Promise<ResumeUploadResponse> {
  for (let i = 0; i < attempts; i++) {
    try {
      return await retryProcessing(resumeId);
    } catch (e) {
      if (i === attempts - 1 || !isRetryableFailure(e)) throw e;
      await new Promise(r => setTimeout(r, 2 ** i * 1000));
    }
  }
  throw new Error('unreachable');
}

Prevention

When it happens

Trigger: Non-2xx from the retry-processing endpoint: resume not found (404), backend refuses retry because the resume is not in a failed state (409/400), auth expired (401), or the AI pipeline itself fails again immediately (500/502).

Common situations: Users click 'Retry processing' on a resume record that was already fixed or deleted; the backend LLM quota is exhausted; or the frontend session token expired between page load and the click.

Related errors


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