Skip to content
Puppeteer · error message

Puppeteer: Attempted to use detached Frame

RetryableFrames

Last verified

The exact message
Error: Attempted to use detached Frame 'A1B2C3D4E5F6A7B8C9D0E1F2A3B4C5D6'.

What it means

A Frame object in Puppeteer represents one frame in the page tree: the main frame or an iframe. When that frame is removed from the page, Puppeteer marks the object as detached, and any later call on it (evaluate, $, click, waitForSelector, or calls on handles that belong to it) throws this error. The quoted value is Chrome's internal frame ID.

It appears in two situations. With iframes, the embedding page removed or rebuilt the iframe, which is common with payment fields, captcha widgets and ads. With the main frame, it usually means the whole page or tab was closed or swapped, often because the script kept using a page object after the site opened a new tab and closed the old one, or after the browser crashed.

What is not wrong: the selector or code you were running inside the frame.

What it looks like

async function payFrame(page) {
  const el = await page.waitForSelector('iframe[name="card"]', { visible: true });
  return el.contentFrame();
}

const frame = await payFrame(page);
await frame.locator('input[name="cardnumber"]').fill('4242424242424242');

Why it happens

  • The parent page removed or replaced the iframe (widget re-render, route change).
  • A Frame obtained from page.frames() or contentFrame() was cached and used after a navigation.
  • The page or tab owning the frame was closed or crashed.
  • Concurrent tasks share a page and one of them navigated it away.

How to fix it

  1. Re-acquire the frame right before using it, from the iframe element: await (await page.waitForSelector('iframe#pay')).contentFrame().
  2. After any navigation, discard old Frame objects and look them up again.
  3. Use page.on('framedetached') to log when and which frames disappear.
  4. Give concurrent tasks separate pages so one task's navigation cannot detach another's frames.

How to stop it recurring

Look frames up by a stable attribute every time you need them instead of storing Frame objects. Wait for third-party widgets to finish rendering before typing into them. If a site opens new tabs, track them with browser.waitForTarget() and switch explicitly.

Official documentation: pptr.dev/api/puppeteer.frame. See all Puppeteer error messages.

Related errors

Definitions

Quick answers

What does "Attempted to use detached Frame" mean in Puppeteer?

A Frame object in Puppeteer represents one frame in the page tree: the main frame or an iframe. When that frame is removed from the page, Puppeteer marks the object as detached, and any later call on it ( evaluate , $ , click , waitForSelector , or calls on handles that belong to it) throws this error. The quoted value is Chrome's internal frame ID. It appears in two situations.

How do I fix "Attempted to use detached Frame"?

1. Re-acquire the frame right before using it, from the iframe element: await (await page.waitForSelector('iframe#pay')).contentFrame(). 2. After any navigation, discard old Frame objects and look them up again. 3. Use page.on('framedetached') to log when and which frames disappear. 4. Give concurrent tasks separate pages so one task's navigation cannot detach another's frames.

Run browser automation you can watch and take over

Autonoly runs each job in a real cloud Chromium browser driven by Playwright. Timeouts and detached elements still happen; the difference is that you can watch the run live, see the step that failed, and take control of the browser to finish it.

Also see Live browser control.