puppeteer/puppeteer · error · Error

Could not find DevToolsActivePort for ${options.channel} at

Error message

Could not find DevToolsActivePort for ${options.channel} at ${portPath}

What it means

Umbrella error thrown by the channel-based connect branch when ANY error occurs while reading or parsing DevToolsActivePort or opening the resulting WebSocket. The original error is attached as `cause`. The message reports the channel and the path that failed.

Source

Thrown at packages/puppeteer-core/src/common/BrowserConnector.ts:181

        throw new Error(`Invalid DevToolsActivePort '${fileContent}' found`);
      }
      const port = parseInt(rawPort, 10);
      if (isNaN(port) || port <= 0 || port > 65535) {
        throw new Error(`Invalid port '${rawPort}' found`);
      }
      const browserWSEndpoint = `ws://localhost:${port}${rawPath}`;
      const WebSocketClass = await getWebSocketTransportClass();
      const connectionTransport = await WebSocketClass.create(
        browserWSEndpoint,
        headers,
        options.logger,
      );
      return {
        connectionTransport: connectionTransport,
        endpointUrl: browserWSEndpoint,
      };
    } catch (error) {
      throw new Error(
        `Could not find DevToolsActivePort for ${options.channel} at ${portPath}`,
        {
          cause: error,
        },
      );
    }
  }
  throw new Error('Invalid connection options');
}

async function getWSEndpoint(
  browserURL: string,
  headers?: Record<string, string>,
): Promise<string> {
  const endpointURL = new URL('/json/version', browserURL);

  try {
    const result = await globalThis.fetch(endpointURL.toString(), {

View on GitHub (pinned to d484e21c17)

Solutions

  1. Inspect error.cause to find the real failure (ENOENT, EACCES, Invalid port, WS reject).
  2. Ensure Chrome for Testing / the chosen channel is actually running with --remote-debugging-port.
  3. Use puppeteer.launch() to have puppeteer start Chrome itself, avoiding stale-port issues.
  4. Prefer browserWSEndpoint when you know the endpoint directly.

Example fix

// before
try { await puppeteer.connect({ channel: 'chrome' }); }
catch (e) { /* opaque error */ }

// after
try { await puppeteer.connect({ channel: 'chrome' }); }
catch (e) { console.error(e.message, e.cause); }
// or: launch Chrome yourself
const browser = await puppeteer.launch({ channel: 'chrome' });
Defensive patterns

Strategy: try-catch

Validate before calling

// Pre-flight: confirm Chrome is running and DevTools port file exists.
import fs from 'node:fs';
if (!fs.existsSync(portPath)) {
  throw new Error('Chrome not running or DevTools not enabled');
}
await puppeteer.connect({ channel: 'chrome' });

Type guard

// No type-level guard; this is a runtime/IO failure. Inspect error.cause instead.

Try / catch

try { await puppeteer.connect({ channel: 'chrome' }); }
catch (e) {
  console.error(e.message, e.cause);
  if (e.cause?.code === 'ENOENT') { /* Chrome not running */ }
  else if (e.cause?.code === 'EACCES') { /* permission denied */ }
  else throw e;
}

Prevention

When it happens

Trigger: Any failure inside the try-block: file not found, permission denied, invalid content (211/212), or the WebSocket transport failing to connect to ws://localhost:<port><path>. The catch wraps it with channel + path context.

Common situations: Connecting via channel while Chrome is not running (ENOENT); Chrome running but DevTools not enabled; port already released because Chrome shut down between detection and connect; firewall blocking localhost WS.

Related errors


AI-assisted analysis of puppeteer/puppeteer@d484e21c17 (2026-08-12). Data as JSON: /api/errors/9262c4941155f878. Report an issue: GitHub.