garrytan/gstack · error · BrowseClientError
127
127
Error message
browse resolve exited 127: browse binary not found.
make-pdf needs browse (the gstack Chromium daemon) to render PDFs.
Tried:
- $GSTACK_BROWSE_BIN (${env.GSTACK_BROWSE_BIN || "unset"})
- $BROWSE_BIN (${env.BROWSE_BIN || "unset"})
- sibling: ${siblingCandidates.join(", ")}
- global: ${globalPath}
- PATH: `browse`
To fix: run gstack setup from the gstack repo:
cd ~/.claude/skills/gstack && ./setup
Or set GSTACK_BROWSE_BIN explicitly:
${GSTACK_BROWSE_BIN export/setx line} What it means
BrowseClientError with exitCode 127 thrown by resolveBrowseBin() when the browse binary cannot be located in any of five resolution tiers: GSTACK_BROWSE_BIN/BROWSE_BIN env overrides, sibling dist paths, the global ~/.claude/skills/gstack install, or PATH. make-pdf needs browse (the gstack Chromium daemon) to render PDFs. The message is a canonical setup recipe, not just a path.
Source
Thrown at make-pdf/src/browseClient.ts:134
];
for (const candidate of siblingCandidates) {
const found = findExecutable(candidate);
if (found) return found;
}
// 4: global install.
const home = os.homedir();
const globalPath = path.join(home, ".claude/skills/gstack/browse/dist/browse");
const globalFound = findExecutable(globalPath);
if (globalFound) return globalFound;
// 5: PATH lookup via Bun.which — handles Windows PATHEXT natively (no `which`
// dependency on cmd.exe / PowerShell, no `where`-vs-`which` branch).
const PATH = env.PATH ?? env.Path ?? '';
const onPath = Bun.which('browse', { PATH });
if (onPath) return onPath;
throw new BrowseClientError(
/* exitCode */ 127,
"resolve",
[
"browse binary not found.",
"",
"make-pdf needs browse (the gstack Chromium daemon) to render PDFs.",
"Tried:",
` - $GSTACK_BROWSE_BIN (${env.GSTACK_BROWSE_BIN || "unset"})`,
` - $BROWSE_BIN (${env.BROWSE_BIN || "unset"})`,
` - sibling: ${siblingCandidates.join(", ")}`,
` - global: ${globalPath}`,
" - PATH: `browse`",
"",
"To fix: run gstack setup from the gstack repo:",
" cd ~/.claude/skills/gstack && ./setup",
"",
"Or set GSTACK_BROWSE_BIN explicitly:",
process.platform === "win32"View on GitHub (pinned to 94993f7401)
Solutions
- Run `cd ~/.claude/skills/gstack && ./setup` to (re)build and install browse.
- Set GSTACK_BROWSE_BIN to an absolute path of an existing browse binary (`export GSTACK_BROWSE_BIN=/path/to/browse`).
- Confirm the binary is executable: `chmod +x <browse>` (POSIX) or unblock it (Windows).
- Run `bun run build` in the gstack repo to produce browse/dist/browse, then retry.
Example fix
# before $ pdf report.md Error: browse resolve exited 127: browse binary not found. ... # after — install browse, then render $ cd ~/.claude/skills/gstack && ./setup $ export GSTACK_BROWSE_BIN="$HOME/.claude/skills/gstack/browse/dist/browse" $ pdf report.md
Defensive patterns
Strategy: validation
Validate before calling
import { resolveBrowseBin, BrowseClientError } from './browseClient';
import fs from 'node:fs';
function ensureBrowseAvailable(env = process.env): void {
try {
const bin = resolveBrowseBin(env);
if (!fs.existsSync(bin)) throw new Error(`resolved browse binary missing: ${bin}`);
} catch (e) {
if (e instanceof BrowseClientError && e.exitCode === 127) {
throw new Error('Run `cd ~/.claude/skills/gstack && ./setup` before rendering PDFs.');
}
throw e;
}
}
ensureBrowseAvailable(); Type guard
import { BrowseClientError } from './browseClient';
function isBrowseMissing(e: unknown): e is BrowseClientError {
return e instanceof BrowseClientError && e.exitCode === 127;
} Try / catch
try {
await generate(opts);
} catch (e) {
if (isBrowseMissing(e)) {
console.error('browse not installed — run ./setup from the gstack repo, then retry.');
process.exit(127);
}
throw e;
} Prevention
- Run gstack ./setup once on every new machine/CI worker.
- Set GSTACK_BROWSE_BIN to an absolute path in CI for reproducibility.
- Pin the browse build and make-pdf client to the same release.
- Confirm the binary is executable (chmod +x / unblock on Windows).
When it happens
Trigger: First make-pdf run on a machine where gstack ./setup was never run; GSTACK_BROWSE_BIN points to a deleted/moved binary; a compiled pdf binary invoked from a directory whose sibling/browse layout differs from the expected dist/ layout; PATH lacks the browse install dir; the global install was partially deleted.
Common situations: Fresh CI worker without the gstack skill installed; a user who only `bun install`-ed make-pdf without building browse; moving the repo after setting a relative GSTACK_BROWSE_BIN; macOS Gatekeeper quarantine stripping the executable bit; Windows where the .exe extension requires PATHEXT resolution that Bun.which handles but a hand-set env var does not.
Related errors
- gbrain CLI not on PATH
- browse ${args[0] || "unknown"} exited ${exitCode}: ${stderr}
- 1
- diagram-render bundle did not become ready in the browse tab
- diagram-render bundle not found. Tried: ${candidates.map((c)
AI-assisted analysis of garrytan/gstack@94993f7401 (2026-08-12).
Data as JSON: /api/errors/badaff75c1e0ba06.
Report an issue: GitHub.