{"record":{"id":"a5d0c6788fe3c57b","repo":"heygen-com/hyperframes","slug":"build-zip-no-linux64-chrome-headless-shell-binar","errorCode":null,"errorMessage":"[build-zip] no linux64 chrome-headless-shell binary found under ${baseDir}.","messagePattern":"\\[build-zip\\] no linux64 chrome-headless-shell binary found under (.+?)\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/aws-lambda/scripts/build-zip.ts","lineNumber":470,"sourceCode":"    );\n  }\n  // Sort by numeric semver descending. `sort().reverse()` is lexicographic,\n  // which silently picks \"99.0.0\" over \"131.0.0\" once Chrome ships\n  // three-digit majors that aren't strictly width-aligned. `compareSemver`\n  // returns negative/zero/positive on (a, b), so descending = `b - a`.\n  const versions = readdirSync(baseDir).sort((a, b) => compareSemver(b, a));\n  for (const v of versions) {\n    const candidate = join(baseDir, v, \"chrome-headless-shell-linux64\", \"chrome-headless-shell\");\n    if (existsSync(candidate)) {\n      const dest = join(stagingDir, \"bin\", \"chrome-headless-shell\");\n      mkdirSync(dirname(dest), { recursive: true });\n      cpSync(candidate, dest);\n      chmodSync(dest, 0o755);\n      console.log(`[build-zip] staged chrome-headless-shell (${v}) → bin/chrome-headless-shell`);\n      return;\n    }\n  }\n  throw new Error(`[build-zip] no linux64 chrome-headless-shell binary found under ${baseDir}.`);\n}\n\n/**\n * Compare two semver-shaped strings like \"131.0.6778.108\". Treats any\n * non-numeric directory name as `-Infinity` so it sorts to the bottom\n * (Puppeteer's cache layout sometimes includes `latest` or branch tags).\n * Used by `stageChromeHeadlessShell` to pick the newest cached Chrome\n * without tripping on the lexicographic \"99 > 131\" trap.\n */\nfunction compareSemver(a: string, b: string): number {\n  const partsA = a.split(\".\").map((s) => Number.parseInt(s, 10));\n  const partsB = b.split(\".\").map((s) => Number.parseInt(s, 10));\n  const len = Math.max(partsA.length, partsB.length);\n  for (let i = 0; i < len; i++) {\n    const ai = partsA[i] ?? 0;\n    const bi = partsB[i] ?? 0;\n    if (Number.isNaN(ai) && Number.isNaN(bi)) continue;\n    if (Number.isNaN(ai)) return -1;","sourceCodeStart":452,"sourceCodeEnd":488,"githubUrl":"https://github.com/heygen-com/hyperframes/blob/c2996c8626135db5253519359d8a063d3bafad8d/packages/aws-lambda/scripts/build-zip.ts#L452-L488","documentation":"The Puppeteer cache directory exists, but the build iterates cached version directories (sorted by semver descending) looking for <version>/chrome-headless-shell-linux64/chrome-headless-shell. If no version directory contains the linux64 binary, it throws.","triggerScenarios":"The Puppeteer cache has Chrome versions but none have the chrome-headless-shell-linux64 subdirectory — only macOS or Windows variants were cached, or the cache has full Chrome but not chrome-headless-shell.","commonSituations":"Building on macOS where @puppeteer/browsers install fetched chrome-headless-shell-mac-64 or chrome-headless-shell-mac-arm64; cache was populated on a non-Linux host.","solutions":["Install the linux64 variant: npx --yes @puppeteer/browsers install chrome-headless-shell@stable --platform=linux --path ~/.cache/puppeteer","Build inside a linux/amd64 Docker container so the cache is populated with linux binaries.","Switch to --source=sparticuz to avoid the chrome-headless-shell dependency entirely."],"exampleFix":null,"handlingStrategy":"validation","validationCode":"import { existsSync, readdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nconst home = process.env.HOME ?? \"/root\";\nconst baseDir = join(home, \".cache\", \"puppeteer\", \"chrome-headless-shell\");\nconst hasLinux64 = readdirSync(baseDir).some((v) =>\n  existsSync(join(baseDir, v, \"chrome-headless-shell-linux64\", \"chrome-headless-shell\")),\n);\nif (!hasLinux64) {\n  console.error(\"No linux64 chrome-headless-shell cached. Install with --platform=linux.\");\n  process.exit(1);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Install chrome-headless-shell with --platform=linux on non-Linux hosts.","Build in a linux/amd64 container so the cache is populated correctly.","Use --source=sparticuz to avoid this path entirely."],"tags":["chrome-headless-shell","cross-platform","build"],"backgroundTag":null,"analyzedSha":"c2996c8626135db5253519359d8a063d3bafad8d","analyzedAt":"2026-08-12T22:18:56.877Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}