garrytan/gstack · error · Error
Server failed to start: ${errorLog}
Error message
Server failed to start:
${errorLog} What it means
Error "Server failed to start: ${errorLog}" thrown in garrytan/gstack.
Source
Thrown at browse/src/cli.ts:367
// Use HTTP health check (not isProcessAlive) — it's fast (~instant ECONNREFUSED)
// and works reliably on all platforms including Windows.
const start = Date.now();
while (Date.now() - start < MAX_START_WAIT) {
const state = readState();
if (state && await isServerHealthy(state.port)) {
return state;
}
await Bun.sleep(100);
}
// Server didn't start in time — check the on-disk startup error log.
// Both platforms now spawn with stdio: 'ignore', so the server writes
// errors to disk for the CLI to read (see server.ts start().catch).
const errorLogPath = path.join(config.stateDir, 'browse-startup-error.log');
try {
const errorLog = fs.readFileSync(errorLogPath, 'utf-8').trim();
if (errorLog) {
throw new Error(`Server failed to start:\n${errorLog}`);
}
} catch (e: any) {
if (e.code !== 'ENOENT') throw e;
}
throw new Error(`Server failed to start within ${MAX_START_WAIT / 1000}s`);
}
/**
* Acquire an exclusive lockfile to prevent concurrent ensureServer() races (TOCTOU).
* Returns a cleanup function that releases the lock.
*/
function acquireServerLock(): (() => void) | null {
const lockPath = `${config.stateFile}.lock`;
try {
// 'wx' — create exclusively, fails if file already exists (atomic check-and-create)
// Using string flag instead of numeric constants for Bun Windows compatibility
const fd = fs.openSync(lockPath, 'wx');
fs.writeSync(fd, `${process.pid}\n`);View on GitHub (pinned to 94993f7401)
When it happens
Trigger: Thrown at browse/src/cli.ts:367 when the library encounters an invalid state.
Common situations: See trigger scenarios.
AI-assisted analysis of garrytan/gstack@94993f7401 (2026-08-12).
Data as JSON: /api/errors/018e00b0d07b70bf.
Report an issue: GitHub.