Closed bug report

Windows: loadPuppeteer passes C:\ paths to import(), and chromePath only knows the Linux layout

AdityaAngajala · 19d ago ·closed by Colby Knox

Windows: loadPuppeteer passes C:\ paths to import(), so doctor and Generate report puppeteer-core missing; chromePath only knows the Linux layout

Windows 11, hero-studio 0.21.5, Node 26.5.0, puppeteer-core 25.12.0 installed in ~/.cache/hero-studio.

1. puppeteer-core is installed but never loads

  • renderer-paths.puppeteerPath() returns C:\Users\<user>\.cache\hero-studio\node_modules\puppeteer-core\lib\puppeteer\puppeteer-core.js, and the server's quick status says the local renderer is OK.
  • doctor.mjs loadPuppeteer() then does await import(c) on that path. On Windows that throws ERR_UNSUPPORTED_ESM_URL_SCHEME ("On Windows, absolute paths must be valid file:// URLs. Received protocol 'c:'"). The empty catch {} swallows it.
  • Result: doctor prints FAIL puppeteer-core: puppeteer-core not found with an npm fix that changes nothing, and render-hero.mjs (which uses the same loader) would fail at Generate. The server's gate and the doctor disagree about the same files.
  • Fix: await import(pathToFileURL(c).href) for anything that is not already a URL. Workaround: set PUPPETEER_CORE to the file:///C:/... URL of the entry file; doctor then reports "resolves (25.12.0)" and render-hero.mjs renders.

2. Chrome is not found at its standard Windows install

  • chromePath() checks CHROME, then only ~/.cache/puppeteer/chrome/*/chrome-linux64/chrome.
  • With Chrome installed at C:\Program Files\Google\Chrome\Application\chrome.exe, doctor said "Chrome not found" and suggested npx @puppeteer/browsers install.
  • Fix: also look for chrome-win64\chrome.exe and chrome-mac* under the puppeteer cache, plus the system installs (%ProgramFiles%, %ProgramFiles(x86)%, %LOCALAPPDATA%\Google\Chrome\Application, /Applications/Google Chrome.app/...). Workaround: set CHROME.

2 Replies

Colby Knox · 19d ago

Both fixed.

  1. loadPuppeteer now imports through pathToFileURL(...) for anything that is not already a URL, so a C:\\ path loads. The candidate errors are no longer thrown away: HERO_STUDIO_DEBUG=1 prints them.
  2. Chrome is looked for in the puppeteer cache under every OS's folder name (chrome-win64\\chrome.exe, chrome-mac-arm64 and chrome-mac-x64, chrome-linux64), then at the standard installs: %ProgramFiles%, %ProgramFiles(x86)% and %LOCALAPPDATA%\\Google\\Chrome\\Application\\chrome.exe on Windows, /Applications/Google Chrome.app on macOS, and /usr/bin/google-chrome and chromium on Linux. CHROME still wins.

Shipped in hero-studio 0.22.0 (adom-wiki pkg install adom/hero-studio). Tested here on Linux, with the Windows and macOS branches driven by explicit inputs and a simulated desktop environment (no container proxy, no container key, a fresh home directory). I have no Windows machine to run it on, so please confirm on your desktop; if anything still breaks there, reopen with the output.

Colby Knox · 19d ago

Follow-up: this is now verified on a real Windows 11 machine (Node 24, PowerShell 5.1, Git for Windows, Chrome in Program Files), not only in the simulation:

  • With the adom-wiki fix for adom/adom-wiki-cli#62, adom-wiki pkg install adom/hero-studio ran install.sh. It wrote the wrapper and hero-studio.cmd and installed puppeteer-core into the user cache.
  • hero-studio doctor ran through the .cmd from PowerShell. puppeteer-core loaded, Chrome was found, the headless launch passed, and pup read as optional.
  • A server started from PowerShell, where HOME is not set, kept its state under C:\Users\<user>\.adom\instances and logged where it looked.
  • That server read the private adom/brand as confirmed through the desktop session.
  • Generate refused with STAMP_FAILED while Pillow was missing. After py -m pip install pillow it produced a stamped 2000x1250 PNG.
  • pose --surface browser opened the studio on 127.0.0.1 and waited for Generate.

That run found three more problems, fixed in hero-studio 0.22.1:

  • The .cmd picked WSL's bash. It now runs Git's bash by path, and only one interpreter, so a failing command is never retried.
  • doctor printed a Node/libuv assertion on exit on Windows.
  • A missing Pillow was remembered until the server restarted.

Log in to reply.