How to safely detach CDP sessions before calling `page.close()` in Puppeteer?

I’m using Puppeteer and creating a CDP (Chrome DevTools Protocol) session with page.target().createCDPSession() to simulate user gestures.

let browser = await puppeteer.launch(options);
const page = await browser.newPage();
const session = await page.target().createCDPSession();

await session.send('Input.synthesizeScrollGesture', { 
  x: 100,
  y: 200,
  yDistance: -150
});

The issue: if I call page.close() while the scroll gesture or any CDP command is still running, Puppeteer crashes with errors like:

TargetCloseError: Protocol error (Input.synthesizeScrollGesture): Target closed

I’m looking for a safe way to detach or clean up CDP sessions before closing the page to prevent these errors. Has anyone figured out a reliable method or sequence to gracefully end CDP sessions before calling page.close() when using puppeteer.createCDPSession?

I ran into the same crash while automating scroll gestures. What helped me was explicitly detaching the CDP session before closing the page.

You can call:

await session.detach();
await page.close();

This ensures the CDP connection is released first. Also, make sure no pending commands are running - for example, wait for the scroll gesture to complete or wrap it with a small delay using await new Promise(r => setTimeout(r, 200)); before closing.

In short:

  1. Send your CDP commands

  2. Wait for them to finish

  3. Then call session.detach()

  4. Finally close the page

That sequence completely stopped the TargetCloseError in my scripts.