{"record":{"id":"a31c7fb85b7eb7af","repo":"microsoft/playwright","slug":"response-status-response-statustext-respons","errorCode":null,"errorMessage":"${response.status} ${response.statusText}${responseText}","messagePattern":"\\$\\{response\\.status\\} \\$\\{response\\.statusText\\}\\$\\{responseText\\}","errorType":"http","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/fetch.ts","lineNumber":239,"sourceCode":"    };\n    // rejectUnauthorized = undefined is treated as true in Node.js 12.\n    if (params.ignoreHTTPSErrors || defaults.ignoreHTTPSErrors)\n      options.rejectUnauthorized = false;\n\n    const postData = serializePostData(params, headers);\n    if (postData)\n      setHeader(headers, 'content-length', String(postData.byteLength));\n    const { body, log, response } = await this._sendRequestWithRetries(progress, requestUrl, options, postData, params.maxRetries);\n    const failOnStatusCode = params.failOnStatusCode !== undefined ? params.failOnStatusCode : !!defaults.failOnStatusCode;\n    if (failOnStatusCode && (response.status < 200 || response.status >= 400)) {\n      let responseText = '';\n      if (body.byteLength) {\n        let text = body.toString('utf8');\n        if (text.length > 1000)\n          text = text.substring(0, 997) + '...';\n        responseText = `\\nResponse text:\\n${text}`;\n      }\n      throw new Error(`${response.status} ${response.statusText}${responseText}`);\n    }\n    const fetchUid = this._storeResponseBody(body);\n    this.fetchLog.set(fetchUid, log);\n    return { ...response, fetchUid };\n  }\n\n  private _parseSetCookieHeader(responseUrl: string, setCookie: string[] | undefined): channels.NetworkCookie[] {\n    if (!setCookie)\n      return [];\n    const url = new URL(responseUrl);\n    // https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4\n    const defaultPath = '/' + url.pathname.substr(1).split('/').slice(0, -1).join('/');\n    const cookies: channels.NetworkCookie[] = [];\n    for (const header of setCookie) {\n      // Decode cookie value?\n      const cookie: channels.NetworkCookie | null = parseCookie(header);\n      if (!cookie)\n        continue;","sourceCodeStart":221,"sourceCodeEnd":257,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/fetch.ts#L221-L257","documentation":"Thrown by APIRequestContext.fetch when failOnStatusCode is enabled and the HTTP response status is outside the 2xx/3xx success range (status < 200 or status >= 400). The message carries the status code, status text, and up to the first 1000 chars of the response body so the caller can see the server's error payload.","triggerScenarios":"Calling request.get/post/put/head/etc. (or APIRequestContext.fetch) with failOnStatusCode: true against an endpoint that returns 4xx (e.g. 404 Not Found, 401 Unauthorized, 403 Forbidden) or 5xx (500, 502, 503). It also fires when failOnStatusCode is set as a default on the APIRequestContext/BrowserContext options.","commonSituations":"Testing an API that returns error bodies; hitting auth-protected endpoints without credentials; pointing at a wrong base URL returning 404; behind a proxy/gateway returning 502/503; backend returning 500 during a deploy.","solutions":["Set failOnStatusCode: false on the call (or remove it) and inspect response.status()/response.text() manually.","Fix the request: correct the URL/method/headers/auth so the endpoint returns 2xx.","Add the required authentication (httpCredentials, Authorization header) before the call.","If you want non-2xx to be a soft path, branch on response.ok() instead of relying on the throw."],"exampleFix":"// before\nconst resp = await request.get(url, { failOnStatusCode: true }); // throws on 404\n// after\nconst resp = await request.get(url);\nif (!resp.ok()) console.warn(resp.status(), await resp.text());","handlingStrategy":"validation","validationCode":"// Check endpoint health before asserting on status\nconst resp = await request.get(url);\nexpect(resp.ok()).toBe(true); // or branch manually","typeGuard":"// Type guard via the public API surface\nfunction isApiError(e: unknown, code: number) {\n  return e instanceof Error && e.message.startsWith(String(code) + ' ');\n}","tryCatchPattern":"// Only retry on transient 5xx when failOnStatusCode is off\nconst resp = await request.get(url);\nif (resp.status() >= 500) { /* retry policy */ }","preventionTips":["Prefer response.ok() branching over failOnStatusCode for resilient tests.","Keep auth/credentials in the context rather than per-call.","Validate the URL and base URL at config time."],"tags":["network","api-request","http-status"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}