{"record":{"id":"32a9ddc22f929618","repo":"microsoft/playwright","slug":"clientcertificates-origin-is-required","errorCode":null,"errorMessage":"clientCertificates.origin is required","messagePattern":"clientCertificates\\.origin is required","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/playwright-core/src/server/browserContext.ts","lineNumber":800,"sourceCode":"export function verifyGeolocation(geolocation?: types.Geolocation): asserts geolocation is types.Geolocation {\n  if (!geolocation)\n    return;\n  geolocation.accuracy = geolocation.accuracy || 0;\n  const { longitude, latitude, accuracy } = geolocation;\n  if (longitude < -180 || longitude > 180)\n    throw new Error(`geolocation.longitude: precondition -180 <= LONGITUDE <= 180 failed.`);\n  if (latitude < -90 || latitude > 90)\n    throw new Error(`geolocation.latitude: precondition -90 <= LATITUDE <= 90 failed.`);\n  if (accuracy < 0)\n    throw new Error(`geolocation.accuracy: precondition 0 <= ACCURACY failed.`);\n}\n\nexport function verifyClientCertificates(clientCertificates?: types.BrowserContextOptions['clientCertificates']) {\n  if (!clientCertificates)\n    return;\n  for (const cert of clientCertificates) {\n    if (!cert.origin)\n      throw new Error(`clientCertificates.origin is required`);\n    if (!cert.cert && !cert.key && !cert.passphrase && !cert.pfx)\n      throw new Error('None of cert, key, passphrase or pfx is specified');\n    if (cert.cert && !cert.key)\n      throw new Error('cert is specified without key');\n    if (!cert.cert && cert.key)\n      throw new Error('key is specified without cert');\n    if (cert.pfx && (cert.cert || cert.key))\n      throw new Error('pfx is specified together with cert, key or passphrase');\n  }\n}\n\nexport function normalizeProxySettings(proxy: types.ProxySettings): types.ProxySettings {\n  let { server, bypass } = proxy;\n  let url;\n  try {\n    // new URL('127.0.0.1:8080') throws\n    // new URL('localhost:8080') fails to parse host or protocol\n    // In both of these cases, we need to try re-parse URL with `http://` prefix.","sourceCodeStart":782,"sourceCodeEnd":818,"githubUrl":"https://github.com/microsoft/playwright/blob/c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6/packages/playwright-core/src/server/browserContext.ts#L782-L818","documentation":"`verifyClientCertificates` requires each client-certificate entry to have an `origin` (the host the cert applies to). Without origin, Playwright can't match the certificate to outgoing requests.","triggerScenarios":"`browser.newContext({ clientCertificates: [{ cert: '...', key: '...' }] })` — an entry missing the `origin` field.","commonSituations":"Incomplete TLS client-auth configs; assuming Playwright applies certs globally rather than per-origin; partial refactor of cert loading.","solutions":["Add `origin: 'https://host'` to each clientCertificates entry","Group cert/key/passphrase/pfx under the correct origin","Validate each entry has origin before launching the context"],"exampleFix":"// before\nawait browser.newContext({\n  clientCertificates: [{ cert: 'c.pem', key: 'k.pem' }]\n});\n\n// after\nawait browser.newContext({\n  clientCertificates: [{ origin: 'https://example.com', cert: 'c.pem', key: 'k.pem' }]\n});","handlingStrategy":"validation","validationCode":"function validateClientCerts(certs?: { origin?: string; cert?: string; key?: string; passphrase?: string; pfx?: string }[]) {\n  if (!certs) return;\n  for (const c of certs) {\n    if (!c.origin) throw new Error('Each clientCertificates entry requires an `origin` (e.g. https://host).');\n    if (!c.cert && !c.key && !c.passphrase && !c.pfx)\n      throw new Error(`clientCertificates entry for ${c.origin} has no cert/key/passphrase/pfx`);\n    if (c.cert && !c.key) throw new Error(`cert requires key for ${c.origin}`);\n    if (!c.cert && c.key) throw new Error(`key requires cert for ${c.origin}`);\n    if (c.pfx && (c.cert || c.key)) throw new Error(`pfx is exclusive of cert/key for ${c.origin}`);\n  }\n}\nvalidateClientCerts(opts.clientCertificates);\nawait browser.newContext(opts);","typeGuard":"function isValidCertEntry(c: unknown): c is { origin: string; cert?: string; key?: string; passphrase?: string; pfx?: string } {\n  return !!c && typeof c === 'object' && typeof (c as any).origin === 'string' && (c as any).origin.length > 0;\n}","tryCatchPattern":null,"preventionTips":["Always include `origin` on every clientCertificates entry","Validate the full cert/key/pfx matrix before launch","Centralize TLS config validation to fail fast with a clear message"],"tags":["client-certificates","validation","config","tls"],"backgroundTag":null,"analyzedSha":"c8fc3bf8d31542d59b4d4d9eaab1df93ff541dc6","analyzedAt":"2026-08-12T07:26:36.950Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}