transloadit/uppy · error · Error

Failed request with status

Error message

Failed request with status: ${res.status}. ${res.statusText}

What it means

This generic Error is thrown from the catch branch of handleJSONResponse: the HTTP request already failed (non-OK status), and additionally the response body could not be parsed as JSON (e.g. an HTML error page from a proxy). The message combines status and statusText, and the original parse failure is attached via { cause }. It exists so callers still get a meaningful error when the server's error body is not JSON.

Solutions

  1. Inspect the thrown error's status (parse from message) and the cause to see what the body actually was
  2. Fix the companionUrl / proxy configuration so JSON responses (and errors) come from Companion itself
  3. Check the Network tab to see the raw response body for the failing request
  4. If a proxy intercepts errors, configure it to pass through upstream JSON error responses

Example fix

// before
// companionUrl misrouted; proxy returns HTML 502 page
const data = await companionRequestClient.get('/url') // throws generic Error

// after
new Url(uppy, { companionUrl: 'https://companion.example.com' })
// nginx: proxy_pass http://companion:3020; and avoid custom error_page interception
Defensive patterns

Strategy: try-catch

Validate before calling

null

Type guard

null

Try / catch

try {
  await client.get('/url')
} catch (err) {
  const status = Number(/status: (\d+)/.exec(err.message)?.[1])
  if (status >= 500) { /* gateway issue, retry later */ }
}

Prevention

When it happens

Trigger: A RequestClient request returns a non-OK status AND res.json() throws (body is HTML/plain text) — typical for 502/504 gateway errors from nginx, a Companion route served behind a misconfigured proxy, or hitting a non-Companion URL that returns an error page.

Common situations: companionUrl points to a wrong path; reverse proxy returns HTML error pages (502 Bad Gateway, Cloudflare challenge); Companion crashed and something else answers; rate-limit pages from CDNs.

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 transloadit/uppy@5d4dedd02a (2026-08-28). Data as JSON: /api/errors/13a005201aa8323d. Report an issue: GitHub.

Appendix: source

Thrown at packages/@uppy/core/src/companion-client/RequestClient.ts:75

async function handleJSONResponse<ResJson>(res: Response): Promise<ResJson> {
  if (res.status === authErrorStatusCode) {
    throw new AuthError()
  }

  if (res.ok) {
    return res.json()
  }

  let errMsg = `Failed request with status: ${res.status}. ${res.statusText}`
  let errData: any
  try {
    errData = await res.json()

    if (errData.message) errMsg = `${errMsg} message: ${errData.message}`
    if (errData.requestId) errMsg = `${errMsg} request-Id: ${errData.requestId}`
  } catch (cause) {
    // if the response contains invalid JSON, let's ignore the error data
    throw new Error(errMsg, { cause })
  }

  if (res.status >= 400 && res.status <= 499 && errData.message) {
    throw new UserFacingApiError(errData.message)
  }

  throw new HttpError({ statusCode: res.status, message: errMsg })
}

function emitSocketProgress<M extends Meta, B extends Body>(
  uploader: { uppy: Uppy<M, B> },
  progressData: {
    progress: string // pre-formatted percentage number as a string
    bytesTotal: number
    bytesUploaded: number
  },
  file: UppyFile<M, B>,
): void {

View on GitHub (pinned to 5d4dedd02a)