puppeteer/puppeteer · error · UnsupportedOperation

WebDriver BiDi does not support `hasCrossSiteAncestor` yet.

Error message

WebDriver BiDi does not support `hasCrossSiteAncestor` yet.

What it means

Thrown by convertCookiesPartitionKeyFromPuppeteerToBiDi() when a cookie partition key object has `hasCrossSiteAncestor: true`. WebDriver BiDi's setCookie takes only a `sourceOrigin` partition key and cannot express the cross-site-ancestor flag, so its presence is rejected. UnsupportedOperation.

Source

Thrown at packages/puppeteer-core/src/bidi/Page.ts:1230

    default:
      return Bidi.Network.SameSite.Default;
  }
}

export function convertCookiesExpiryCdpToBiDi(
  expiry: number | undefined,
): number | undefined {
  return [undefined, -1].includes(expiry) ? undefined : expiry;
}

export function convertCookiesPartitionKeyFromPuppeteerToBiDi(
  partitionKey: CookiePartitionKey | string | undefined,
): string | undefined {
  if (partitionKey === undefined || typeof partitionKey === 'string') {
    return partitionKey;
  }
  if (partitionKey.hasCrossSiteAncestor) {
    throw new UnsupportedOperation(
      'WebDriver BiDi does not support `hasCrossSiteAncestor` yet.',
    );
  }
  return partitionKey.sourceOrigin;
}

View on GitHub (pinned to d484e21c17)

Solutions

  1. Drop `hasCrossSiteAncestor` from the partition key before setting the cookie under BiDi.
  2. If the flag is semantically required, use CDP (`protocol: 'cdp'`) where it is honored.
  3. When replaying storage state, sanitize partition keys: `{sourceOrigin: pk.sourceOrigin}`.
  4. Track this as a known BiDi limitation until the spec adds the field.

Example fix

// before
await page.setCookie({
  name: 'id', value: '1',
  partitionKey: {sourceOrigin: 'https://example', hasCrossSiteAncestor: true},
}); // throws

// after
await page.setCookie({
  name: 'id', value: '1',
  partitionKey: {sourceOrigin: 'https://example'},
});
Defensive patterns

Strategy: validation

Validate before calling

function sanitizePartitionKey(pk: any) {
  if (pk && typeof pk === 'object') {
    return {sourceOrigin: pk.sourceOrigin}; // drop hasCrossSiteAncestor
  }
  return pk;
}

Type guard

const partitionKeyBidiSafe = (pk: any): boolean =>
  !(pk && typeof pk === 'object' && pk.hasCrossSiteAncestor);

Try / catch

import {UnsupportedOperation} from 'puppeteer';
try {
  await page.setCookie({...cookie, partitionKey});
} catch (e) {
  if (e instanceof UnsupportedOperation && /hasCrossSiteAncestor/.test(e.message)) {
    await page.setCookie({...cookie, partitionKey: {sourceOrigin: partitionKey.sourceOrigin}});
  } else { throw e; }
}

Prevention

When it happens

Trigger: Calling `page.setCookie({...partitionKey: {sourceOrigin, hasCrossSiteAncestor: true}})` or `context.addCookies([...])` with such a partition key under BiDi. The conversion helper at Page.ts:1229 fires when the cookie is normalized.

Common situations: Reading cookies back from CDP (which may populate hasCrossSiteAncestor) and re-setting them under BiDi; storage-state replay files captured with the flag; partitioned-cookie tests asserting cross-site ancestor semantics.

Related errors


AI-assisted analysis of puppeteer/puppeteer@d484e21c17 (2026-08-12). Data as JSON: /api/errors/6fa1d12f1c7d8e8c. Report an issue: GitHub.