{"record":{"id":"417a9950ac72e891","repo":"CloakHQ/CloakBrowser","slug":"unsupported-platform-platform-arch-support","errorCode":null,"errorMessage":"Unsupported platform: ${platform} ${arch}. Supported: ${supported}","messagePattern":"Unsupported platform: (.+?) (.+?)\\. Supported: (.+?)","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"js/src/config.ts","lineNumber":107,"sourceCode":"export function getChromiumVersion(): string {\n  const tag = getPlatformTag();\n  return PLATFORM_CHROMIUM_VERSIONS[tag] ?? CHROMIUM_VERSION;\n}\n\nexport function getPlatformTag(): string {\n  const platform = process.platform;\n  const arch = process.arch;\n\n  // Map Node.js platform/arch to our tag format\n  let key: string;\n  if (platform === \"linux\" && arch === \"x64\") key = \"linux-x64\";\n  else if (platform === \"linux\" && arch === \"arm64\") key = \"linux-arm64\";\n  else if (platform === \"darwin\" && arch === \"arm64\") key = \"darwin-arm64\";\n  else if (platform === \"darwin\" && arch === \"x64\") key = \"darwin-x64\";\n  else if (platform === \"win32\" && arch === \"x64\") key = \"win32-x64\";\n  else {\n    const supported = Object.values(SUPPORTED_PLATFORMS).join(\", \");\n    throw new Error(\n      `Unsupported platform: ${platform} ${arch}. Supported: ${supported}`\n    );\n  }\n\n  return SUPPORTED_PLATFORMS[key]!;\n}\n\n// ---------------------------------------------------------------------------\n// Binary cache paths\n// ---------------------------------------------------------------------------\nexport function getCacheDir(): string {\n  const custom = process.env.CLOAKBROWSER_CACHE_DIR;\n  if (custom) return custom;\n  return path.join(os.homedir(), \".cloakbrowser\");\n}\n\nexport function getBinaryDir(version?: string, pro = false): string {\n  const suffix = pro ? \"-pro\" : \"\";","sourceCodeStart":89,"sourceCodeEnd":125,"githubUrl":"https://github.com/CloakHQ/CloakBrowser/blob/d6bad5de261bedf025280ace1d14e800aee13923/js/src/config.ts#L89-L125","documentation":"StealthWorldUnavailableError is raised inside human_scroll_into_view (scroll.py:107) when page._stealth_world is None. This happens on headed launches with no_viewport=True: page.viewport_size is None, so the code must read live window geometry through the isolated world, and if that world was never attached (stealth mode disabled or the page predates it), the error propagates.","triggerScenarios":"Calling human_scroll_into_view on a page launched with no_viewport (headed mode) where the stealth isolated world is missing — e.g. humanization used on a non-stealth context, a page created before stealth attach, or the world attribute cleared after teardown.","commonSituations":"Mixing stealth and plain Playwright contexts; disabling stealth mode but still calling humanized scroll helpers; headed default launch (no_viewport) combined with a stripped-down launcher; version change that stopped attaching _stealth_world eagerly.","solutions":["Launch the page through the stealth launcher so _stealth_world is attached before any humanized scroll call.","Pass an explicit viewport at launch (headless or headed with viewport=...) so the no_viewport code path is never taken.","Verify getattr(page, '_stealth_world', None) is not None before calling human_scroll_into_view; if None, re-attach the stealth world or recreate the page."],"exampleFix":"// before\npage = browser.new_page()  # plain page, no stealth world\nhuman_scroll_into_view(page, sel, get_box, cfg)\n\n// after\npage = stealth_browser.new_page(viewport={'width': 1280, 'height': 800})\nhuman_scroll_into_view(page, sel, get_box, cfg)","handlingStrategy":"validation","validationCode":"world = getattr(page, \"_stealth_world\", None)\nif world is None:\n    raise RuntimeError(\"stealth world not attached; launch via stealth launcher\")","typeGuard":"def has_stealth_world(page) -> bool:\n    return getattr(page, \"_stealth_world\", None) is not None","tryCatchPattern":"try:\n    human_scroll_into_view(page, sel, get_box, cfg)\nexcept StealthWorldUnavailableError:\n    page = stealth_context.new_page(viewport={'width':1280,'height':800})\n    # redo work on stealth page","preventionTips":["Always create pages through the stealth launcher","Pass an explicit viewport in headed mode to skip the no_viewport path","Never mix plain Playwright pages with humanized scroll helpers"],"tags":["stealth","viewport","headed-mode","isolated-world"],"backgroundTag":"missing-required-context","analyzedSha":"d6bad5de261bedf025280ace1d14e800aee13923","analyzedAt":"2026-08-28T14:13:12.918Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}