ScreenshotNeo

BlogHow-to

How to Cancel a Puppeteer Device Request Prompt

Cancel a Puppeteer device request with DeviceRequestPrompt.cancel(). Learn how to avoid timing races, handle errors, and tell device prompts apart from dialogs.

By the ScreenshotNeo team4 October 20264 min read

Call and await cancel() on the DeviceRequestPrompt returned by page.waitForDevicePrompt(). Start waiting before the page action that triggers the request; Puppeteer does not return a prompt that is already active.

const [devicePrompt] = await Promise.all([
  page.waitForDevicePrompt(),
  page.click('#connect-device'),
]);

await devicePrompt.cancel();

Replace #connect-device with the selector for the control that requests a device. This is Puppeteer’s device-request API, commonly used for WebBluetooth. It is separate from JavaScript dialogs such as alert(). See the Puppeteer API reference and DeviceRequestPrompt reference.

Cancel a device request step by step

  1. Make sure the page is ready and the control that starts the request is available.
  2. Start page.waitForDevicePrompt() before clicking the control.
  3. Await the prompt returned by the coordinated operation.
  4. Call await devicePrompt.cancel() to decline the request.

cancel() returns a promise, so awaiting it ensures the cancellation operation has completed before subsequent automation proceeds.

Runnable example

This example shows the relevant Puppeteer calls in context. Supply a page URL and selector appropriate to your application:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  try {
    const page = await browser.newPage();
    await page.goto('https://example.com');

    const [devicePrompt] = await Promise.all([
      page.waitForDevicePrompt(),
      page.click('#connect-device'),
    ]);

    await devicePrompt.cancel();
    console.log('Device request canceled');
  } finally {
    await browser.close();
  }
})().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

The target page must actually request a device when the selected control is activated. The example uses a placeholder URL and selector; replace them with values from the page you automate.

Why the wait must come first

waitForDevicePrompt() is an event wait, not a way to retrieve a prompt that is already open. If the click happens first and the wait is registered afterward, the prompt can be missed and the wait may time out. Promise.all starts both operations together, registering the wait as the click triggers the request.

Do not trigger the device request in one step and then call waitForDevicePrompt() in a later step. Keep the wait and triggering action coordinated as in the example.

Cancel, select, or wait for a device

Intent API action Result
Decline the request await devicePrompt.cancel() Cancels the device prompt.
Choose a listed device await devicePrompt.select(device) Selects the supplied device from the prompt.
Wait for a matching device devicePrompt.waitForDevice(filter, options) Waits for a device matching the supplied filter.

Use cancel() when the automation should decline the request. Use the selection methods only when the test or workflow is intended to connect to a device. The prompt exposes the currently available selectable devices.

Common errors and fixes

Symptom Likely cause Fix
waitForDevicePrompt() times out The triggering action did not request a device, the selector did not activate the intended control, or the wait was installed after the prompt appeared. Verify the page action and selector, then register the wait before triggering the request using the coordinated pattern.
The prompt is missed intermittently A race allows the request action to happen before the wait is active. Put the wait and trigger in the same Promise.all operation.
cancel is not a function The value is not a Puppeteer DeviceRequestPrompt, often because the result was not taken from waitForDevicePrompt(). Check that you await the method and use the returned prompt object.
A JavaScript alert remains open A browser dialog was confused with a device request prompt. Handle JavaScript dialogs with Puppeteer’s dialog API. DeviceRequestPrompt.cancel() applies to a device request, not an alert or confirm dialog.
Cancellation appears not to affect the page The page may handle a declined device request in its own way, or the request may not be the one expected. Confirm that the device prompt was captured and observe the application’s behavior after the request is canceled.

Reliability, versions, and practical notes

  • Await the operation: cancel() returns Promise<void>; await it before continuing.
  • Use the documented prompt object: do not substitute dialog dismissal or a page-level click for canceling this API prompt.
  • Check the API reference for your installed Puppeteer version: the referenced current documentation labels version 25.12.0, and software APIs can change.
  • No extra package is needed for cancellation itself: the method is part of Puppeteer’s prompt API. Browser setup and device availability depend on the page and automation environment.

The operation adds an event wait and a cancellation call to the automation flow. The cited API documentation does not provide a benchmark, fixed timing guarantee, or cost figure for this operation; avoid treating it as a measured performance claim.

Or skip the browser setup

If your goal is to capture a page as an image or PDF rather than automate a device prompt, ScreenshotNeo is a website screenshot API and MCP server. Its one-call API captures a URL; see the ScreenshotNeo 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
import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await require('node:fs/promises').writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

Cookie banners, popups, and chat widgets are removed before the shot. 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.

Create a free ScreenshotNeo account and get 1,000 screenshots a month with no card.

FAQ

Does canceling choose a device?

No. Cancellation declines the request. Choosing a device is a separate action using select(device).

Can I cancel a prompt that is already open?

You can cancel a prompt once you have its DeviceRequestPrompt object. However, waitForDevicePrompt() will not retrieve a prompt that was already active before the wait began, so install the wait before triggering the request.

Is this the same as dismissing a browser alert?

No. A device request prompt and a JavaScript dialog are different browser interactions with different Puppeteer APIs.