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

The fix is to use Chrome DevTools Protocol’s intentionally misspelled field, grantUniveralAccess. grantUniversalAccess is not the accepted JSON key, so Chrome may reject it or silently leave the option disabled. You must also obtain a fresh frame ID immediately before calling Page.createIsolatedWorld; a navigation or iframe replacement can make an earlier ID invalid.

The correct flag and a working Puppeteer example

Although “Universal” is grammatically correct, the wire protocol spells the property grantUniveralAccess (the second “s” is missing). Puppeteer’s FrameManager sends that spelling, and the generated CDP binding defines it as a boolean. If omitted, the protocol default is false.

This example creates a CDP session, gets the current main-frame ID, creates a named isolated world, and evaluates code in the returned execution context:

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
const page = await browser.newPage();
const client = await page.createCDPSession();

try {
  await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });

  const frame = page.mainFrame();
  if (!frame || frame.isDetached()) {
    throw new Error('The main frame is no longer attached');
  }

  // _id is the frame identifier expected by the CDP command.
  const { executionContextId } = await client.send('Page.createIsolatedWorld', {
    frameId: frame._id,
    worldName: '__my_isolated_world__',
    grantUniveralAccess: true
  });

  const evaluated = await client.send('Runtime.evaluate', {
    contextId: executionContextId,
    expression: '({ title: document.title, href: location.href })',
    returnByValue: true
  });

  console.log(evaluated.result.value);
} finally {
  await client.detach().catch(() => {});
  await browser.close();
}

frame._id is an internal Puppeteer property rather than a long-term public API guarantee. That is one reason to resolve the frame just before the CDP call and to keep this low-level integration isolated in one helper. For ordinary DOM work, page.evaluate() and the public frame methods are less brittle.

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

Why grantUniversalAccess fails

Page.createIsolatedWorld validates parameters against the CDP schema. The schema contains grantUniveralAccess, not the corrected spelling. Sending the latter produces an unknown-parameter error in some Chrome/Puppeteer combinations; in others the option is simply not applied. Changing only that key fixes the spelling problem.

The value is a boolean. Set it to true only when the isolated world genuinely needs the protocol’s universal-access behavior. The CDP documentation describes this as a powerful option and cautions that it should be used carefully. It applies to the isolated world in the frame named by frameId; it is not a browser-wide switch.

Understanding the No frame for given id found error

If the spelling is correct but the command fails with:

Protocol error (Page.createIsolatedWorld): No frame for given id found

the usual cause is a frame-lifecycle race. Puppeteer enumerates frames, then sends the command asynchronously. A redirect, navigation, iframe replacement, or detachment can invalidate the ID in that short interval. Puppeteer issue #7902 records this exact failure during isolated-world initialization.

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

Use a fresh frame ID

Do not cache a frame ID across navigation. Resolve the target frame after navigation has reached the state you need and immediately before client.send(). For an iframe, locate the current object from page.frames() rather than retaining an object from a previous document.

Confirm attachment

Check frame.isDetached() and, when appropriate, verify that the frame is still present in page.frames(). A detached frame is gone; do not continue evaluating in its old execution context.

Retry against a new context

Catch only the known stale-frame error, allow the page to settle, reacquire the frame, and retry a bounded number of times. Repeating the same request with the same ID cannot repair a detached frame.

async function createWorldWithRetry(page, client, getFrame, attempts = 3) {
  const delays = [50, 100, 200];

  for (let attempt = 0; attempt < attempts; attempt++) {
    const frame = getFrame();
    if (!frame || frame.isDetached()) {
      throw new Error('Target frame is unavailable');
    }

    try {
      return await client.send('Page.createIsolatedWorld', {
        frameId: frame._id,
        worldName: '__my_isolated_world__',
        grantUniveralAccess: true
      });
    } catch (error) {
      const message = String(error?.message || error);
      const stale = message.includes('No frame for given id found');
      if (!stale || attempt === attempts - 1) throw error;
      await new Promise(resolve => setTimeout(resolve, delays[attempt]));
    }
  }
}

const result = await createWorldWithRetry(
  page,
  client,
  () => page.frames().find(frame => frame === page.mainFrame())
);
console.log(result.executionContextId);

Choose a frame selector appropriate to your application. The main-frame comparison above is deliberately simple; for an iframe, match its current URL, name, or an element’s content frame, then perform the same attachment check.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

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

Execution contexts, navigation, and cleanup

The returned executionContextId

The command returns an executionContextId. Pass that ID to Runtime.evaluate when you need to run JavaScript specifically in the new isolated world. Keep the context ID scoped to the current document and CDP session.

Navigation invalidates contexts

A reload, redirect, or frame replacement can dispose the document and its execution contexts. Puppeteer’s IsolatedWorld implementation waits for a replacement context and reruns pending work when one is installed. Your own CDP code should follow the same principle: after navigation, reacquire the frame, create a new world if necessary, and obtain a new context ID. Never assume an ID from the previous document remains usable.

Dispose the session

Detach the CDP session when the page or browser context closes. This prevents pending protocol work from outliving the target and makes shutdown errors easier to distinguish from real page failures.

What universal access does—and does not—change

The flag grants the documented access behavior to the isolated world created in one specified frame. It does not disable every browser security boundary. Cross-origin DOM access, CORS requests, document isolation, and site-isolation behavior still depend on Chrome’s security model and on the context that performs the operation. A successful Page.createIsolatedWorld call therefore does not guarantee that a cross-origin fetch() or DOM read will succeed.

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

If your goal is routine automation, prefer these public Puppeteer APIs:

  • page.evaluate() for code in the page’s normal execution world.
  • Frame evaluation methods for work targeted at a particular current frame.
  • Request interception and navigation controls for network and page-flow tasks.

Use the raw CDP command when you explicitly need a named isolated world or this protocol-level behavior. Puppeteer’s FrameManager and IsolatedWorld internals can change between releases, so code coupled to them should be covered by integration tests.

Choosing an approach for cross-origin testing

Approach Use it when Main trade-off
Public Puppeteer APIs You need normal DOM evaluation, navigation, or request handling. Less protocol control, but a more stable supported surface.
Raw Page.createIsolatedWorld through CDP You explicitly require a named isolated world or protocol-level access. You must use the misspelled key and handle frame/context races yourself.
Browser-wide --disable-web-security-style settings A controlled test harness intentionally needs broad cross-origin behavior. Much broader security impact; not equivalent to the isolated-world flag and unsuitable for ordinary production automation.

Common failures and precise fixes

“Unknown parameter” or the option has no effect

Inspect the outgoing JSON. The property must be exactly grantUniveralAccess, with a capital U and the protocol’s missing “s”. Do not “correct” it in a wrapper or TypeScript type.

“No frame for given id found”

Treat the ID as stale. Wait for the current navigation or redirect to settle, reacquire the frame from page.frames(), verify it is attached, and retry with a short bounded backoff. If the iframe is repeatedly replaced, move world creation to a point after the application inserts its final iframe.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
The SQL Programming Language: .
  • Used Book in Good Condition

Evaluation runs in the wrong world

Creating a world does not change where later Puppeteer evaluations run. Use the returned context ID with Runtime.evaluate, or use a Puppeteer frame/world abstraction that explicitly targets the isolated world. Confirm the result with a world-specific marker rather than assuming the page’s default context changed.

Cross-origin requests still fail

The flag is not a universal CORS bypass. Check the target server’s CORS response, the origin of the requesting context, and whether the operation is a DOM access or a network request. If the requirement is a controlled test-only browser policy, configure that harness separately and isolate it from production browsing.

Errors appear during shutdown

Stop scheduling CDP work before closing the page, detach the session, and then close the browser. Ignore only expected detach errors during cleanup; do not suppress protocol errors raised while the page is still active.

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

Performance and reliability considerations

  • Create one CDP session per page and reuse it for related commands instead of opening a session for every evaluation.
  • Create the isolated world once per document, then reuse its context until navigation disposes it.
  • Keep retries bounded. A permanently detached iframe should fail clearly rather than causing an unending loop.
  • Wait for the specific application state you need; “network idle” alone does not prevent a later client-side iframe replacement.
  • Log the frame URL, navigation event, attempt number, and protocol error. Those details distinguish a typo from a lifecycle race.

Or skip the browser setup

If your actual goal is a clean image or PDF of a web page rather than JavaScript inside an isolated world, ScreenshotNeo provides a one-request screenshot API and an MCP server for AI agents. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing result.

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

See the full parameter reference in the ScreenshotNeo documentation. A direct call is:

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

The same request in Python:

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)

And in Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

ScreenshotNeo also exposes take_screenshot, get_page_info, and capture_pdf through MCP, so Claude, Cursor, or another MCP client can request captures without your maintaining a browser session. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account to try it.

Final checklist

  • Send grantUniveralAccess, not grantUniversalAccess.
  • Resolve the frame immediately before Page.createIsolatedWorld.
  • Reject detached frames and reacquire after navigation.
  • Retry only stale-frame failures, with a bounded delay.
  • Use the returned execution context for isolated-world evaluation.
  • Recreate the world after a document navigation and detach the CDP session during cleanup.

Frequently Asked Questions

Does an isolated world survive a full page reload?

No. A reload creates a new document and disposes the old execution context. Create the world again after the new frame is attached.

Can I reuse an executionContextId on another page?

No. The ID is scoped to the current CDP target and document; obtain a new one whenever the target or document changes.

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

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.