{"record":{"id":"fbddd97348916c5c","repo":"garrytan/gstack","slug":"cookie-domain-c-domain-does-not-match-current","errorCode":null,"errorMessage":"Cookie domain \"${c.domain}\" does not match current page domain \"${defaultDomain}\". Use the target site first.","messagePattern":"Cookie domain \"(.+?)\" does not match current page domain \"(.+?)\"\\. Use the target site first\\.","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"warning","filePath":"browse/src/write-commands.ts","lineNumber":674,"sourceCode":"      }\n      if (!fs.existsSync(filePath)) throw new Error(`File not found: ${filePath}`);\n      const raw = fs.readFileSync(filePath, 'utf-8');\n      let cookies: any[];\n      try { cookies = JSON.parse(raw); } catch (err: any) { throw new Error(`Invalid JSON in ${filePath}: ${err?.message || err}`); }\n      if (!Array.isArray(cookies)) throw new Error('Cookie file must contain a JSON array');\n\n      // Auto-fill domain from current page URL when missing (consistent with cookie command)\n      const pageUrl = new URL(page.url());\n      const defaultDomain = pageUrl.hostname;\n\n      for (const c of cookies) {\n        if (!c.name || c.value === undefined) throw new Error('Each cookie must have \"name\" and \"value\" fields');\n        if (!c.domain) {\n          c.domain = defaultDomain;\n        } else {\n          const cookieDomain = c.domain.startsWith('.') ? c.domain.slice(1) : c.domain;\n          if (cookieDomain !== defaultDomain && !defaultDomain.endsWith('.' + cookieDomain)) {\n            throw new Error(`Cookie domain \"${c.domain}\" does not match current page domain \"${defaultDomain}\". Use the target site first.`);\n          }\n        }\n        if (!c.path) c.path = '/';\n      }\n\n      await page.context().addCookies(cookies);\n      const importedDomains = [...new Set(cookies.map((c: any) => c.domain).filter(Boolean))];\n      if (importedDomains.length > 0) bm.trackCookieImportDomains(importedDomains);\n      return `Loaded ${cookies.length} cookies from ${filePath}`;\n    }\n\n    case 'cookie-import-browser': {\n      // Two modes:\n      // 1. Direct CLI import: cookie-import-browser <browser> --domain <domain> [--profile <profile>]\n      //    Requires --domain (or --all to explicitly import everything).\n      // 2. Open picker UI: cookie-import-browser [browser] (interactive domain selection)\n      const browserArg = args[0];\n      const domainIdx = args.indexOf('--domain');","sourceCodeStart":656,"sourceCodeEnd":692,"githubUrl":"https://github.com/garrytan/gstack/blob/94993f74012782fd94416dd44b8314f6363a13a4/browse/src/write-commands.ts#L656-L692","documentation":"Thrown by `browse cookie-import` when a cookie's explicit `domain` field does not match the current page hostname. The check normalizes a leading dot off the cookie domain, then requires either an exact match or that the page hostname ends with `.` + cookie domain (parent-domain match). This prevents importing cookies for site B while the browser is navigated to site A, which would be a cross-site cookie injection. The message directs the user to navigate to the target site first.","triggerScenarios":"Browser is on `example.com` but the JSON contains a cookie with `domain: 'other-site.com'`; browser is on `app.example.com` and a cookie has `domain: 'example.com'` (this PASSES the parent check); browser is on `example.com` and a cookie has `domain: '.example.com'` (dot stripped, exact match, PASSES).","commonSituations":"User exported cookies from a browser session for site B and tries to import while still navigated to site A; the JSON contains cookies for multiple domains but the page is only on one of them; the user forgot the `browse navigate <url>` step before importing.","solutions":["Navigate to the target site first: `browse navigate https://target-site.com`, then re-run the import.","If the JSON contains cookies for multiple domains, split it by domain and import each batch after navigating to the matching site.","Omit the `domain` field from cookie objects — the command auto-fills it from the current page hostname, which always matches.","Confirm the cookie domain and page hostname agree up to a parent-domain suffix."],"exampleFix":"// before (page is on about:blank)\nawait runBrowseCommand(['cookie-import', fp]); // fp has domain: 'target.com'\n\n// after\nawait runBrowseCommand(['navigate', 'https://target.com']);\nawait runBrowseCommand(['cookie-import', fp]);","handlingStrategy":"validation","validationCode":"function domainsCompatible(cookieDomain: string, pageHostname: string): boolean {\n  const d = cookieDomain.startsWith('.') ? cookieDomain.slice(1) : cookieDomain;\n  return d === pageHostname || pageHostname.endsWith('.' + d);\n}\nfunction ensureCookiesMatchPage(cookies: any[], pageHostname: string): void {\n  for (const c of cookies) {\n    if (c.domain && !domainsCompatible(c.domain, pageHostname)) {\n      throw new Error(`Cookie domain ${c.domain} does not match page ${pageHostname}`);\n    }\n  }\n}","typeGuard":"function cookieDomainMatchesPage(c: { domain?: string }, pageHostname: string): boolean {\n  if (!c.domain) return true;\n  const d = c.domain.startsWith('.') ? c.domain.slice(1) : c.domain;\n  return d === pageHostname || pageHostname.endsWith('.' + d);\n}","tryCatchPattern":null,"preventionTips":["Navigate to the target site before importing its cookies.","Omit the domain field to auto-fill from the current page hostname.","Split multi-domain JSON into per-site batches and import each after navigating."],"tags":["cookies","import","security","domain-mismatch","cross-site","browse-command"],"backgroundTag":null,"analyzedSha":"94993f74012782fd94416dd44b8314f6363a13a4","analyzedAt":"2026-08-12T04:06:23.140Z","schemaVersion":2},"datasetVersion":"2026-08-12T13:17:24.610Z"}