Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use response.ok() to check whether a Puppeteer HTTP response has a 2xx status. If your test requires one specific code, compare response.status() directly. For navigation, first guard against a null response.

Check a response returned by navigation

page.goto() returns an HTTPResponse for a navigation when one is available. Check the response rather than assuming that a completed navigation means the HTTP request succeeded:

const response = await page.goto('https://example.com');

if (!response) {
  throw new Error('Navigation produced no HTTP response');
}

if (!response.ok()) {
  throw new Error(`HTTP ${response.status()} for ${response.url()}`);
}

The Puppeteer page.goto() documentation notes that the result can be null when navigating to about:blank or to the same URL with a different hash. The guard prevents calling response methods on null.

A non-2xx status does not necessarily make goto() throw a navigation exception. In particular, Puppeteer documents that in headless shell a valid HTTP status such as 404 or 500 does not cause goto() to throw. Inspect the returned response if HTTP status is part of the test.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose between ok() and status()

Check Use it when What it tells you
response.ok() Any successful HTTP status is acceptable. Returns true for status codes from 200 through 299.
response.status() Your requirement specifies an exact code or custom status policy. Returns the numeric status code, which you can compare or evaluate yourself.

For example, if a test requires exactly 200 rather than any 2xx response, write response.status() === 200. Use the numeric code or ok() as the predicate; status text is not the success check. See the official references for HTTPResponse.ok() and HTTPResponse.status().

Check a response triggered by an action

When a click or other page action causes the request, create the response wait before triggering the action. That way, the response cannot arrive before Puppeteer starts listening.

const responsePromise = page.waitForResponse(
  response => response.url() === 'https://example.com/api/data'
);

await page.click('#load-data');

const response = await responsePromise;
if (!response.ok()) {
  throw new Error(`HTTP ${response.status()} for ${response.url()}`);
}

page.waitForResponse() accepts a URL or predicate and resolves to the matching HTTPResponse. Its documented default timeout is 30 seconds; adjust it through the method options or the page’s default timeout if your application needs a different wait. The official method reference includes examples of matching a response and checking its status.

Distinguish HTTP success from application success

ok() answers only whether the HTTP status is in Puppeteer’s 2xx range. It does not establish that the response body represents a successful operation. An API can return a 2xx status with an application-level error, or your test may require a particular payload.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

In those cases, check the body as well as the status:

const response = await page.waitForResponse(
  response => response.url() === 'https://example.com/api/data'
);

if (!response.ok()) {
  throw new Error(`HTTP ${response.status()}`);
}

const payload = await response.json();
if (payload.error) {
  throw new Error(`Application error: ${payload.error}`);
}

Use the assertion that matches your API’s contract instead of assuming that every 2xx response has the same meaning. Puppeteer’s HTTPResponse reference documents response-body access; response.json() throws if the body is not valid JSON. If the endpoint returns another format, inspect response.text() or the relevant response data instead.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshoot common failures

  • Cannot read properties of null: The navigation may be one of the documented cases where goto() returns null. Check the result before calling ok() or status().
  • The test passes even though the page returned 404 or 500: Navigation completion is not an HTTP-success assertion. Check response.ok() or the exact status explicitly.
  • The response wait times out: Confirm that the predicate matches the actual response URL and that the listener is set up before the click or other action. If the response legitimately takes longer, configure a suitable timeout.
  • A 2xx response still fails the operation: Add an assertion for the application payload; HTTP status success alone does not validate the body.
  • response.json() throws: The body is not valid JSON. Verify the endpoint’s returned format and use text or another suitable parser if it is not JSON.
  • Types or behavior differ in an older project: The surfaced Puppeteer API documentation includes versions 25.10.0 and 25.12.0. Check the installed package’s version and type definitions when working with an older release.

Or skip the browser setup

If your goal is to capture a page rather than test Puppeteer response handling, ScreenshotNeo provides a screenshot API and MCP server. A single GET request can return an image or PDF; see the API documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Cookie banners, popups and chat widgets are removed before capture. Bot checks, blank pages and failed loads are never billed. An MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Sign up for free and get 1,000 screenshots a month with no card.

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.