{"record":{"id":"6fa1d12f1c7d8e8c","repo":"puppeteer/puppeteer","slug":"webdriver-bidi-does-not-support-hascrosssiteances","errorCode":null,"errorMessage":"WebDriver BiDi does not support `hasCrossSiteAncestor` yet.","messagePattern":"WebDriver BiDi does not support `hasCrossSiteAncestor` yet\\.","errorType":"exception","errorClass":"UnsupportedOperation","httpStatus":null,"severity":"error","filePath":"packages/puppeteer-core/src/bidi/Page.ts","lineNumber":1230,"sourceCode":"    default:\n      return Bidi.Network.SameSite.Default;\n  }\n}\n\nexport function convertCookiesExpiryCdpToBiDi(\n  expiry: number | undefined,\n): number | undefined {\n  return [undefined, -1].includes(expiry) ? undefined : expiry;\n}\n\nexport function convertCookiesPartitionKeyFromPuppeteerToBiDi(\n  partitionKey: CookiePartitionKey | string | undefined,\n): string | undefined {\n  if (partitionKey === undefined || typeof partitionKey === 'string') {\n    return partitionKey;\n  }\n  if (partitionKey.hasCrossSiteAncestor) {\n    throw new UnsupportedOperation(\n      'WebDriver BiDi does not support `hasCrossSiteAncestor` yet.',\n    );\n  }\n  return partitionKey.sourceOrigin;\n}\n","sourceCodeStart":1212,"sourceCodeEnd":1236,"githubUrl":"https://github.com/puppeteer/puppeteer/blob/d484e21c17f6023826fefdcdeeb553e04a7aaed8/packages/puppeteer-core/src/bidi/Page.ts#L1212-L1236","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Drop `hasCrossSiteAncestor` from the partition key before setting the cookie under BiDi.","If the flag is semantically required, use CDP (`protocol: 'cdp'`) where it is honored.","When replaying storage state, sanitize partition keys: `{sourceOrigin: pk.sourceOrigin}`.","Track this as a known BiDi limitation until the spec adds the field."],"exampleFix":"// before\nawait page.setCookie({\n  name: 'id', value: '1',\n  partitionKey: {sourceOrigin: 'https://example', hasCrossSiteAncestor: true},\n}); // throws\n\n// after\nawait page.setCookie({\n  name: 'id', value: '1',\n  partitionKey: {sourceOrigin: 'https://example'},\n});","handlingStrategy":"validation","validationCode":"function sanitizePartitionKey(pk: any) {\n  if (pk && typeof pk === 'object') {\n    return {sourceOrigin: pk.sourceOrigin}; // drop hasCrossSiteAncestor\n  }\n  return pk;\n}","typeGuard":"const partitionKeyBidiSafe = (pk: any): boolean =>\n  !(pk && typeof pk === 'object' && pk.hasCrossSiteAncestor);","tryCatchPattern":"import {UnsupportedOperation} from 'puppeteer';\ntry {\n  await page.setCookie({...cookie, partitionKey});\n} catch (e) {\n  if (e instanceof UnsupportedOperation && /hasCrossSiteAncestor/.test(e.message)) {\n    await page.setCookie({...cookie, partitionKey: {sourceOrigin: partitionKey.sourceOrigin}});\n  } else { throw e; }\n}","preventionTips":["When replaying storage state, sanitize partition keys to just sourceOrigin.","Do not round-trip CDP-captured cookies with hasCrossSiteAncestor into BiDi.","Track this as a known BiDi gap for partitioned-cookie tests."],"tags":["cookies","bidi","unsupported-operation","partitioned","cdp-migration"],"backgroundTag":null,"analyzedSha":"d484e21c17f6023826fefdcdeeb553e04a7aaed8","analyzedAt":"2026-08-12T06:33:19.665Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}