davila7/claude-code-templates · warning

⚠️ Could not auto-open browser:

Error message

⚠️  Could not auto-open browser:

What it means

This warning is emitted by ChatsMobile.openBrowser() when the `open` npm package fails to launch the user's default browser at the mobile chat server URL (tunnel or localhost). It is a non-fatal warning: the server keeps running and the user can open the URL manually. Common causes are no display available (SSH/headless), no default browser configured, missing xdg-open, or an invalid/undefined URL.

Solutions

  1. If on SSH, use the printed URL and open it in your local browser manually (the tunnel URL is printed just above the warning).
  2. Set a default browser: `xdg-settings set default-web-browser firefox.desktop` (Linux) or ensure BROWSER env var points to a browser binary.
  3. On headless machines, run with a port-forward instead: `ssh -L 4040:localhost:4040` and open http://localhost:4040 locally.
  4. If you must auto-open, install xdg-utils (`apt install xdg-utils`) or export BROWSER=/usr/bin/chromium.

Example fix

// before
const url = this.tunnelUrl || this.localUrl || `http://localhost:${this.port}`;
await open(url);
// after (guard headless environments)
const url = this.tunnelUrl || this.localUrl || `http://localhost:${this.port}`;
if (!process.env.BROWSER && !process.env.DISPLAY && process.platform === 'linux') {
  console.log(chalk.cyan(`🌐 Open manually: ${url}`));
  return;
}
await open(url);
Defensive patterns

Strategy: fallback

Validate before calling

const isHeadless = process.platform === 'linux' && !process.env.DISPLAY && !process.env.BROWSER;
if (!isHeadless) await open(url); else console.log(`Open manually: ${url}`);

Try / catch

try { await open(url); } catch (e) { console.warn('Could not auto-open browser:', e.message); console.log(`Open manually: ${url}`); }

Prevention

When it happens

Trigger: Running the chats-mobile server in an environment where `open(url)` rejects: headless Linux box with no $DISPLAY, minimal containers without xdg-open/browser, SSH sessions without X forwarding, or a malformed URL (undefined tunnelUrl/localUrl falling back to a bogus value).

Common situations: Running the CLI over SSH, in Docker/WSL without a browser, on a server CI box, or on Linux where xdg-settings has no default Browser configured.


AI-assisted analysis of davila7/claude-code-templates@a0851ed10c (2026-08-28). Data as JSON: /api/errors/05f50c6ab7bbce07. Report an issue: GitHub.

Appendix: source

Thrown at cli-tool/src/chats-mobile.js:1182

        }, 45000);
      });
    } catch (error) {
      console.error(chalk.red('❌ Error setting up Cloudflare Tunnel:'), error.message);
      return null;
    }
  }

  /**
   * Open browser to the mobile chats interface
   */
  async openBrowser() {
    try {
      // Use tunnel URL if available, otherwise local URL
      const url = this.tunnelUrl || this.localUrl || `http://localhost:${this.port}`;
      console.log(chalk.cyan(`🌐 Opening browser to ${url}`));
      await open(url);
    } catch (error) {
      console.warn(chalk.yellow('⚠️  Could not auto-open browser:', error.message));
    }
  }

  /**
   * Stop the server
   */
  async stop() {
    // Prevent multiple stop calls
    if (this.isStopped) {
      return;
    }
    this.isStopped = true;

    if (this.cloudflaredProcess) {
      try {
        this.cloudflaredProcess.kill('SIGTERM');
        this.log('info', chalk.gray('☁️  Cloudflare Tunnel stopped'));
      } catch (error) {

View on GitHub (pinned to a0851ed10c)