srbhr/Resume-Matcher · error · Error

Upload failed for ${fileToUpload.file.name}. Status: ${respo

Error message

Upload failed for ${fileToUpload.file.name}. Status: ${response.status} ${response.statusText} - Server response: ${errorText...}

What it means

useFileUpload builds a descriptive Error when the upload endpoint returns a non-OK HTTP response. It first reads the response body as text (truncated to 200 chars) and appends it to a message containing the filename, status code, and statusText, then throws. This surfaces server-side rejection reasons (validation, auth, size limits) directly to the caller.

Source

Thrown at apps/frontend/hooks/use-file-upload.ts:245

      try {
        const response = await fetch(uploadUrl, {
          method: 'POST',
          body: formData,
        });

        let responseData: Record<string, unknown> = {}; // Initialize for broader scope
        const contentType = response.headers.get('content-type');

        if (!response.ok) {
          let errorDetail = `Upload failed for ${fileToUpload.file.name}. Status: ${response.status} ${response.statusText}`;
          try {
            const errorText = await response.text();
            errorDetail += ` - Server response: ${errorText.substring(0, 200)}${errorText.length > 200 ? '...' : ''}`;
          } catch (textError: unknown) {
            console.warn('Could not read error response text:', textError);
          }
          throw new Error(errorDetail);
        }

        if (contentType && contentType.includes('application/json')) {
          responseData = (await response.json()) as Record<string, unknown>;
        } else {
          // Handle non-JSON or missing Content-Type response if necessary,
          // or assume success if response.ok and no JSON is expected for some cases.
          // For now, we'll assume JSON is expected on success.
          console.warn(
            `Response for ${fileToUpload.file.name} was not JSON. Content-Type: ${contentType}`
          );
          // If JSON is strictly required, this could be an error condition:
          // throw new Error(`Unexpected response type: ${contentType}. Expected JSON.`);
        }

        const successfullyUploadedFile: FileWithPreview = {
          ...fileToUpload,
          file: {

View on GitHub (pinned to 116f9cc3b0)

Solutions

  1. Log the full error message and inspect the embedded status code and server response text to identify the server-side reason
  2. Check authentication: ensure the session cookie is present and not expired (401/403)
  3. Verify the file size is under the server's upload limit and the file type is supported
  4. Retry after fixing the input; for 5xx, check backend logs and retry once the service is healthy

Example fix

// before
await uploadFile(file); // throws generic unhandled error
// after
try {
  await uploadFile(file);
} catch (e) {
  if (e.message.includes('Status: 413')) showMsg('File too large');
  else if (e.message.includes('Status: 401')) await reauthAndRetry();
  else showMsg(`Upload failed: ${e.message}`);
}
Defensive patterns

Strategy: try-catch

Validate before calling

function canUpload(file: File) {
  const MAX = 50 * 1024 * 1024;
  const OK = ['application/pdf', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', 'text/plain'];
  return file.size > 0 && file.size <= MAX && OK.includes(file.type);
}

Type guard

function isUploadError(e: unknown): e is Error & { status?: number } {
  const m = e instanceof Error ? e.message.match(/Status: (\d{3})/) : null;
  if (e instanceof Error && m) (e as any).status = Number(m[1]);
  return e instanceof Error;
}

Try / catch

try {
  await uploadFile(file);
} catch (e) {
  const m = e instanceof Error ? e.message.match(/Status: (\d{3})/) : null;
  if (m && ['401','403'].includes(m[1])) reauth();
  else if (m === '413' || m?.[1] === '413') showMsg('File too large');
  else showMsg(`Upload failed: ${e instanceof Error ? e.message : String(e)}`);
}

Prevention

When it happens

Trigger: Any uploadFile POST to the upload endpoint returning status >= 400: 401 unauthenticated session, 403 CSRF/permission denied, 413 file too large, 415 unsupported file type, 422 validation failure, or 5xx backend crash.

Common situations: User uploads a PDF/DOCX larger than the server's configured max size; expired session cookie causes 401; backend rejects the file extension; reverse proxy returns 502 during backend restart.

Understand the failure class

Background: "API error: {status}" and "HTTP 401/403/404/429/5xx" errors: non-2xx HTTP responses explained — this error's family across 27 libraries.

Related errors


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