garrytan/gstack · error · Error
Server port not available
Error message
Server port not available
What it means
Thrown by `browse cookie-import-browser` in picker-UI mode (no `--domain` and no `--all`) when `bm.serverPort` is falsy (0). The picker UI is served as an HTTP page at `http://127.0.0.1:${port}/cookie-picker`, so without a known port the command cannot construct the URL or open the picker. `serverPort` defaults to 0 and is set by the server bootstrap (`browserManager.serverPort = port`) when the HTTP listener starts.
Source
Thrown at browse/src/write-commands.ts:744
const { domains } = listDomains(browser, profile);
const allDomainNames = domains.map((d: any) => d.domain);
if (allDomainNames.length === 0) {
return `No cookies found in ${browser} (profile: ${profile})`;
}
const result = await importCookies(browser, allDomainNames, profile);
if (result.cookies.length > 0) {
await page.context().addCookies(result.cookies);
bm.trackCookieImportDomains(allDomainNames);
}
const msg = [`Imported ${result.count} cookies across ${Object.keys(result.domainCounts).length} domains from ${browser}`];
msg.push('(used --all: all browser cookies imported, consider --domain for tighter scoping)');
if (result.failed > 0) msg.push(`(${result.failed} failed to decrypt)`);
return msg.join(' ');
}
// Picker UI mode — open in user's browser for interactive domain selection
const port = bm.serverPort;
if (!port) throw new Error('Server port not available');
const browsers = findInstalledBrowsers();
if (browsers.length === 0) {
throw new Error(`No Chromium browsers found. Supported: ${listSupportedBrowserNames().join(', ')}`);
}
const code = generatePickerCode();
const pickerUrl = `http://127.0.0.1:${port}/cookie-picker?code=${code}`;
try {
Bun.spawn(['open', pickerUrl], { stdout: 'ignore', stderr: 'ignore' });
} catch (err: any) {
// open may fail on non-macOS or if 'open' binary is missing — URL is in the message below
if (err?.code !== 'ENOENT' && !err?.message?.includes('spawn')) throw err;
}
return `Cookie picker opened at http://127.0.0.1:${port}/cookie-picker\nDetected browsers: ${browsers.map(b => b.name).join(', ')}\nSelect domains to import, then close the picker when done.\n\nTip: For scripted imports, use --domain <domain> to scope cookies to a single domain.`;
}
View on GitHub (pinned to 94993f7401)
Solutions
- Ensure the browse HTTP server is started before invoking picker mode — `serverPort` is set during server bootstrap.
- Use direct mode (`--domain <domain>`) or `--all` instead of the picker; neither requires the HTTP server.
- Check `bm.serverPort` is non-zero before dispatching the picker command.
- If the server should be running, diagnose why the port binding failed (check for EADDRINUSE, permissions, or a crashed server task).
Example fix
// before (no HTTP server running) await runBrowseCommand(['cookie-import-browser']); // after await runBrowseCommand(['cookie-import-browser', 'comet', '--domain', 'target.com']); // or ensure the server is bootstrapped so bm.serverPort is set
Defensive patterns
Strategy: validation
Validate before calling
function ensurePickerReady(serverPort: number): void {
if (!serverPort) {
throw new Error('cookie picker requires the HTTP server to be running (serverPort is 0)');
}
} Type guard
function isServerPortConfigured(port: number): boolean {
return typeof port === 'number' && port > 0;
} Prevention
- Start the browse HTTP server before invoking picker mode.
- Use --domain or --all modes which do not require the HTTP server.
- Check bm.serverPort is non-zero before dispatching the picker command.
When it happens
Trigger: Running the picker-mode command before the browse HTTP server has bound its port; the server failed to start but the command layer is still reachable; an embedded usage where the BrowserManager is instantiated without the server lifecycle.
Common situations: An SDK user constructs a BrowserManager directly for automation and never starts the HTTP server, then calls the picker command; the server port binding failed silently (EADDRINUSE) and serverPort stayed 0; a test harness invokes write commands without the full server bootstrap.
Related errors
- --domain "${domain}" does not match current page domain "${p
- No Chromium browsers found. Supported: ${listSupportedBrowse
- Usage: browse cookie-import <json-file>
- File not found: ${filePath}
- Invalid JSON in ${filePath}: ${err?.message || err}
AI-assisted analysis of garrytan/gstack@94993f7401 (2026-08-12).
Data as JSON: /api/errors/b1d8b6d771e3bd88.
Report an issue: GitHub.