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

  1. Ensure the browse HTTP server is started before invoking picker mode — `serverPort` is set during server bootstrap.
  2. Use direct mode (`--domain <domain>`) or `--all` instead of the picker; neither requires the HTTP server.
  3. Check `bm.serverPort` is non-zero before dispatching the picker command.
  4. 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

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


AI-assisted analysis of garrytan/gstack@94993f7401 (2026-08-12). Data as JSON: /api/errors/b1d8b6d771e3bd88. Report an issue: GitHub.