microsoft/playwright · error · Error
${response.status} ${response.statusText}${responseText}
Error message
${response.status} ${response.statusText}${responseText} What it means
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.
Source
Thrown at packages/playwright-core/src/server/fetch.ts:239
};
// rejectUnauthorized = undefined is treated as true in Node.js 12.
if (params.ignoreHTTPSErrors || defaults.ignoreHTTPSErrors)
options.rejectUnauthorized = false;
const postData = serializePostData(params, headers);
if (postData)
setHeader(headers, 'content-length', String(postData.byteLength));
const { body, log, response } = await this._sendRequestWithRetries(progress, requestUrl, options, postData, params.maxRetries);
const failOnStatusCode = params.failOnStatusCode !== undefined ? params.failOnStatusCode : !!defaults.failOnStatusCode;
if (failOnStatusCode && (response.status < 200 || response.status >= 400)) {
let responseText = '';
if (body.byteLength) {
let text = body.toString('utf8');
if (text.length > 1000)
text = text.substring(0, 997) + '...';
responseText = `\nResponse text:\n${text}`;
}
throw new Error(`${response.status} ${response.statusText}${responseText}`);
}
const fetchUid = this._storeResponseBody(body);
this.fetchLog.set(fetchUid, log);
return { ...response, fetchUid };
}
private _parseSetCookieHeader(responseUrl: string, setCookie: string[] | undefined): channels.NetworkCookie[] {
if (!setCookie)
return [];
const url = new URL(responseUrl);
// https://datatracker.ietf.org/doc/html/rfc6265#section-5.1.4
const defaultPath = '/' + url.pathname.substr(1).split('/').slice(0, -1).join('/');
const cookies: channels.NetworkCookie[] = [];
for (const header of setCookie) {
// Decode cookie value?
const cookie: channels.NetworkCookie | null = parseCookie(header);
if (!cookie)
continue;View on GitHub (pinned to c8fc3bf8d3)
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.
Example fix
// before
const resp = await request.get(url, { failOnStatusCode: true }); // throws on 404
// after
const resp = await request.get(url);
if (!resp.ok()) console.warn(resp.status(), await resp.text()); Defensive patterns
Strategy: validation
Validate before calling
// Check endpoint health before asserting on status const resp = await request.get(url); expect(resp.ok()).toBe(true); // or branch manually
Type guard
// Type guard via the public API surface
function isApiError(e: unknown, code: number) {
return e instanceof Error && e.message.startsWith(String(code) + ' ');
} Try / catch
// Only retry on transient 5xx when failOnStatusCode is off
const resp = await request.get(url);
if (resp.status() >= 500) { /* retry policy */ } Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Timeout ${options.timeout}ms exceeded
- Malformed endpoint. Did you use BrowserType.launchServer met
- Timeout ${params.timeout}ms exceeded
- ${this._closeReason}
- Socks4 proxy protocol does not support authentication
AI-assisted analysis of microsoft/playwright@c8fc3bf8d3 (2026-08-12).
Data as JSON: /api/errors/a31c7fb85b7eb7af.
Report an issue: GitHub.