Problem
GSTACK_CHROMIUM_PATH is only respected in launchHeaded() but not in launch() (headless mode). Skills like /qa use headless mode by default, so setting GSTACK_CHROMIUM_PATH has no effect.
This breaks browse on NixOS (and likely other non-FHS distros like Guix) where the bundled chromium_headless_shell binary fails because system libraries aren't in standard paths:
chrome-headless-shell: error while loading shared libraries: libglib-2.0.so.0: cannot open shared object file
Root Cause
In browse/dist/server-node.mjs:
- Line ~2491 (
launchHeaded): reads process.env.GSTACK_CHROMIUM_PATH and passes it as executablePath to Playwright
- Line ~2440 (
launch): calls chromium.launch() without executablePath, always using the bundled binary
Workaround
Export LD_LIBRARY_PATH from the system Chrome's Nix wrapper before running browse:
CHROME_LIBS=$(grep "LD_LIBRARY_PATH='" $(readlink -f $(which google-chrome-stable)) | grep "^LD_LIBRARY_PATH='" | sed "s/LD_LIBRARY_PATH='//;s/'.*//" | tr '\n' ':')
export LD_LIBRARY_PATH="$CHROME_LIBS"
This is fragile and has to be done every session.
Suggested Fix
Read GSTACK_CHROMIUM_PATH in launch() too:
async launch() {
+ const executablePath = process.env.GSTACK_CHROMIUM_PATH || undefined;
const launchArgs = [];
// ...
this.browser = await chromium.launch({
headless: useHeadless,
chromiumSandbox: process.platform !== "win32",
+ ...executablePath ? { executablePath } : {},
...launchArgs.length > 0 ? { args: launchArgs } : {}
});
Environment
- OS: NixOS (Linux 6.19.11)
- gstack: v0.15.16.0
- System browser: Google Chrome 146.0.7680.177 (installed via Nix)
GSTACK_CHROMIUM_PATH set to /run/current-system/sw/bin/google-chrome-stable
Problem
GSTACK_CHROMIUM_PATHis only respected inlaunchHeaded()but not inlaunch()(headless mode). Skills like/qause headless mode by default, so settingGSTACK_CHROMIUM_PATHhas no effect.This breaks browse on NixOS (and likely other non-FHS distros like Guix) where the bundled
chromium_headless_shellbinary fails because system libraries aren't in standard paths:Root Cause
In
browse/dist/server-node.mjs:launchHeaded): readsprocess.env.GSTACK_CHROMIUM_PATHand passes it asexecutablePathto Playwrightlaunch): callschromium.launch()withoutexecutablePath, always using the bundled binaryWorkaround
Export
LD_LIBRARY_PATHfrom the system Chrome's Nix wrapper before running browse:This is fragile and has to be done every session.
Suggested Fix
Read
GSTACK_CHROMIUM_PATHinlaunch()too:async launch() { + const executablePath = process.env.GSTACK_CHROMIUM_PATH || undefined; const launchArgs = []; // ... this.browser = await chromium.launch({ headless: useHeadless, chromiumSandbox: process.platform !== "win32", + ...executablePath ? { executablePath } : {}, ...launchArgs.length > 0 ? { args: launchArgs } : {} });Environment
GSTACK_CHROMIUM_PATHset to/run/current-system/sw/bin/google-chrome-stable