{"record":{"id":"300fc3950959e8b3","repo":"microsoft/playwright","slug":"response-body-is-unavailable-for-redirect-response","errorCode":null,"errorMessage":"Response body is unavailable for redirect responses","messagePattern":"Response body is unavailable for redirect responses","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/network.ts","lineNumber":651,"sourceCode":"  }\n\n  async internalSecurityDetails(): Promise<SecurityDetails|null> {\n    return await this._securityDetailsPromise || null;\n  }\n\n  async internalServerAddr(): Promise<RemoteAddr | null> {\n    return await this._serverAddrPromise || null;\n  }\n\n  async internalRawResponseHeaders(): Promise<HeadersArray> {\n    return await this._rawResponseHeadersPromise;\n  }\n\n  internalBody(): Promise<Buffer> {\n    if (!this._contentPromise) {\n      this._contentPromise = this._finishedPromise.then(async () => {\n        if (this._status >= 300 && this._status <= 399)\n          throw new Error('Response body is unavailable for redirect responses');\n        if (this._request._responseBodyOverride) {\n          const { body, isBase64 } = this._request._responseBodyOverride;\n          return Buffer.from(body, isBase64 ? 'base64' : 'utf-8');\n        }\n        try {\n          return await this._getResponseBodyCallback();\n        } catch (e) {\n          if (isProtocolError(e) && e.type === 'error')\n            rewriteErrorMessage(e, e.message + '\\nResponse body is not available for a response that was navigated away from. Read response.body() before triggering any navigation.');\n          throw e;\n        }\n      });\n    }\n    return this._contentPromise;\n  }\n\n  request(): Request {\n    return this._request;","sourceCodeStart":633,"sourceCodeEnd":669,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/network.ts#L633-L669","documentation":"Thrown by Response.internalBody() (which backs response.body() and response.text()) when the response status code is in the 300-399 range, indicating a redirect. Redirect responses have no body by HTTP specification; the browser does not download content for 3xx responses. The check fires inside the _contentPromise lazy initializer after the response is finished.","triggerScenarios":"Calling response.body() or response.text() on a Response object whose status code is 301, 302, 303, 307, or 308. This is common when intercepting all responses via page.on('response') and attempting to read the body of every response, including redirects. Also occurs when explicitly following redirects and inspecting intermediate responses.","commonSituations":"Response listener tries to log or assert on all response bodies without filtering redirects. Test captures a redirect response and calls body() for assertion. page.route() handler inspects the body of a request that received a redirect response. Following redirects but storing references to intermediate redirect Response objects.","solutions":["Check response.status() before calling body(): if (response.status() < 300 || response.status() >= 400) { const body = await response.body(); }.","Filter redirect responses in response listeners: page.on('response', async response => { if (response.headers()['location']) return; ... }).","Use response.url() and response.status() for redirect inspection instead of body()."],"exampleFix":"// before\npage.on('response', async response => {\n  const body = await response.body(); // throws [339] on redirects\n  log(response.url(), body);\n});\n\n// after\npage.on('response', async response => {\n  if (response.status() >= 300 && response.status() <= 399) return;\n  const body = await response.body();\n  log(response.url(), body);\n});","handlingStrategy":"validation","validationCode":"async function safeBody(response) {\n  const status = response.status();\n  if (status >= 300 && status <= 399)\n    return null; // redirect, no body\n  return response.body();\n}","typeGuard":"function hasBody(response: import('@playwright/test').Response): boolean {\n  const status = response.status();\n  return status < 300 || status > 399;\n}","tryCatchPattern":"try {\n  return await response.body();\n} catch (e) {\n  if (e.message === 'Response body is unavailable for redirect responses')\n    return null;\n  throw e;\n}","preventionTips":["Check response.status() before calling body() or text().","Filter redirect responses in page.on('response') listeners.","Use response.headers()['location'] to detect redirects without reading the body."],"tags":["response","body","redirect","network","http"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}