jackwener/OpenCLI · error · CommandExecutionError

Browser page required

Error message

Browser page required

What it means

The v2ex daily command runs with Strategy.COOKIE and browser:true, so the registry should hand the command a live browser page. The command throws CommandExecutionError('Browser page required') when func receives a falsy page, meaning the browser layer failed to launch or attach a page before the command body ran. It guards against dereferencing page.goto on null.

Source

Thrown at clis/v2ex/daily.js:18

/**
 * V2EX Daily Check-in adapter.
 */
import { CommandExecutionError } from '@jackwener/opencli/errors';
import { cli, Strategy } from '@jackwener/opencli/registry';
cli({
    site: 'v2ex',
    name: 'daily',
    access: 'write',
    description: 'V2EX 每日签到并领取铜币',
    domain: 'www.v2ex.com',
    strategy: Strategy.COOKIE,
    browser: true,
    args: [],
    columns: ['status', 'message'],
    func: async (page) => {
        if (!page)
            throw new CommandExecutionError('Browser page required');
        if (process.env.OPENCLI_VERBOSE) {
            console.error('[opencli:v2ex] Navigating to /mission/daily');
        }
        await page.goto('https://www.v2ex.com/mission/daily');
        // Cloudflare challenge bypass wait
        for (let i = 0; i < 5; i++) {
            await new Promise(r => setTimeout(r, 1500));
            const title = await page.evaluate(`() => document.title`);
            if (!title?.includes('Just a moment'))
                break;
            if (process.env.OPENCLI_VERBOSE)
                console.error('[opencli:v2ex] Waiting for Cloudflare...');
        }
        // Evaluate DOM to find if we need to check in
        const checkResult = await page.evaluate(`
      async () => {
        const btn = document.querySelector('input.super.normal.button');
        if (!btn || !btn.value.includes('领取')) {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Install/repair the browser runtime the opencli browser strategy depends on (e.g. playwright install chromium) and its system dependencies.
  2. Re-run the command normally through the CLI so the registry provisions the browser page, rather than calling func directly with no page.
  3. Check earlier logs for a browser-launch failure (profile lock, missing binary) and fix the root cause.
  4. Verify no other process is holding a lock on the browser user-data-dir.

Example fix

// before: invoking the command function directly
await dailyFunc(null);
// after: run through the CLI/registry so a page is provisioned
// $ opencli v2ex daily
Defensive patterns

Strategy: validation

Validate before calling

if (!page || typeof page.goto !== 'function') {
  throw new Error('Browser page unavailable — install the browser runtime (e.g. playwright install chromium) and run via the CLI');
}

Type guard

function hasPage(p) {
  return !!p && typeof p === 'object' && typeof p.goto === 'function' && typeof p.evaluate === 'function';
}

Try / catch

try {
  await runDailyCommand();
} catch (e) {
  if (e.message === 'Browser page required') {
    // fix environment: install browser binary/deps, then retry
  } else throw e;
}

Prevention

When it happens

Trigger: Calling the v2ex daily command when the underlying browser/page object is null or undefined — e.g. browser launch failed upstream, headless environment lacks a browser binary, or the command was invoked through a path that skips browser provisioning.

Common situations: Playwright/Chromium not installed in the environment; running in CI or a container with no browser and missing deps; corrupted browser profile; a registry change or wrapper invoking func without a page.

Related errors


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