jackwener/OpenCLI · error · CommandExecutionError

Command ${fullName(cmd)} requires a browser session but none

Error message

Command ${fullName(cmd)} requires a browser session but none was provided

What it means

This CommandExecutionError is thrown by runCommandFunc when a command that requires a browser (i.e. `cmd.browser !== false`) is invoked without a browser session: the `page` argument (IPage) is null. Commands that drive a real browser tab need an established session; non-browser commands opt out with `browser: false`. It means the caller failed to provide or establish the browser context before dispatch.

Source

Thrown at src/execution.ts:159

    const updated = getRegistry().get(fullName(cmd));
    if (updated?.func) {
      return runCommandFunc(updated, page, kwargs, debug);
    }
    if (updated?.pipeline) return executePipeline(page, updated.pipeline, { args: kwargs, debug });
  }

  if (cmd.func) return runCommandFunc(cmd, page, kwargs, debug);
  if (cmd.pipeline) return executePipeline(page, cmd.pipeline, { args: kwargs, debug });
  throw new CommandExecutionError(
    `Command ${fullName(cmd)} has no func or pipeline`,
    'This is likely a bug in the adapter definition. Please report this issue.',
  );
}

function runCommandFunc(cmd: CliCommand, page: IPage | null, kwargs: CommandArgs, debug: boolean): Promise<unknown> {
  if (cmd.browser === false) return cmd.func!(kwargs, debug);
  if (!page) {
    throw new CommandExecutionError(`Command ${fullName(cmd)} requires a browser session but none was provided`);
  }
  return (cmd as BrowserCliCommand).func!(page, kwargs, debug);
}

function resolvePreNav(cmd: CliCommand): string | null {
  if (cmd.navigateBefore === false) return null;
  if (typeof cmd.navigateBefore === 'string') return cmd.navigateBefore;
  // strategy → navigateBefore expansion already happened in normalizeCommand().
  return null;
}

function urlMatchesDomain(url: string | null | undefined, domain: string | undefined): boolean {
  if (!url || !domain) return false;
  try {
    const hostname = new URL(url).hostname;
    return hostname === domain || hostname.endsWith(`.${domain}`);
  } catch {
    return false;

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Ensure a browser session is started and its page is passed to command execution (launch/connect the browser before running browser commands).
  2. If the command genuinely needs no browser, set `browser: false` on its CliCommand definition so runCommandFunc calls func(kwargs, debug) directly.
  3. Check earlier logs for browser launch/CDP connection failures — the null page is usually a downstream symptom of a failed session setup.
  4. Guard invocations: only dispatch commands to the browser path when a live page handle exists; fail earlier with a clear 'no session' message in your own code.

Example fix

// before
await runCommand(cmd, null, kwargs, debug); // throws: requires a browser session

// after
const page = await browser.newPage();
await runCommand(cmd, page, kwargs, debug);
Defensive patterns

Strategy: validation

Validate before calling

function requireBrowserSession(cmd, page) {
  if (cmd.browser !== false && !page) {
    throw new Error(`Command '${cmd.name}' needs a browser session — start one before dispatch`);
  }
}
// call before runCommand: requireBrowserSession(cmd, page);

Type guard

function hasLivePage(page) {
  return page != null && typeof (page as IPage).navigate === 'function';
}

Try / catch

try {
  await runCommand(cmd, page, kwargs, debug);
} catch (err) {
  if (err instanceof CommandExecutionError && /requires a browser session/.test(err.message)) {
    page = await startBrowserSession();
    await runCommand(cmd, page, kwargs, debug);
  } else {
    throw err;
  }
}

Prevention

When it happens

Trigger: Calling runCommand (-> runCommandFunc) with page === null for a command whose definition does not set `browser: false`; running a browser command in a non-browser execution mode; the browser session failing to launch or being closed before command dispatch; invoking a browser command through a code path that never attaches a page.

Common situations: Running browser-dependent commands where the underlying browser (e.g. via CDP) never connected or crashed earlier in the run; using the library headlessly in CI without a browser available; scripts calling command funcs directly without going through session setup; daemon/extension contexts where the page handle was lost.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/8a2fd717730e4823. Report an issue: GitHub.