jackwener/OpenCLI · error · CommandExecutionError

Browser session required for twitter mute-word

Error message

Browser session required for twitter mute-word

What it means

CommandExecutionError thrown at the start of the mute-word command's func when the injected page object is falsy. This CLI is browser-based: it drives a Playwright-style page to navigate X.com's muted-keyword settings. Without an active browser session the automation cannot run, so it aborts immediately instead of failing later on page.goto.

Solutions

  1. Run the command with browser automation enabled so the registry injects an active page (launch the CLI in its browser/session mode).
  2. Ensure the browser session is started before invoking the command and not closed by an earlier step.
  3. Check upstream browser-launch errors (missing Chromium, display issues in CI) that leave page undefined.
  4. If embedding the CLI, pass a real page object rather than null/undefined.

Example fix

// before
await cliRun('twitter mute-word "spoiler"'); // no browser session configured
// after
const session = await opencli.browser.launch();
await cliRun('twitter mute-word "spoiler"', { browser: session });
await session.close();
Defensive patterns

Strategy: validation

Validate before calling

if (!page) throw new Error('Browser session required: launch the opencli browser session before running twitter mute-word');

Type guard

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

Try / catch

try {
  await run(['twitter', 'mute-word', kw]);
} catch (err) {
  if (err.message.includes('Browser session required')) {
    const session = await opencli.browser.launch();
    await run(['twitter', 'mute-word', kw], { browser: session });
    await session.close();
  } else throw err;
}

Prevention

When it happens

Trigger: Invoking the twitter mute-word command outside a browser-session context (no `page` argument supplied by the opencli registry), e.g. running the CLI in a mode where browser automation was not launched or the session was closed before the command executed.

Common situations: Running the command via a non-browser strategy/registry configuration; browser launch failure upstream left page undefined; invoking the command programmatically without establishing the browser session the CLI expects.

Related errors


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

Appendix: source

Thrown at clis/twitter/mute-word.js:26

    }
    return keyword;
}

cli({
    site: 'twitter',
    name: 'mute-word',
    access: 'write',
    description: 'Add a muted word or phrase on Twitter/X',
    domain: 'x.com',
    strategy: Strategy.UI,
    browser: true,
    args: [
        { name: 'keyword', type: 'string', positional: true, required: true, help: 'Word or phrase to mute' },
    ],
    columns: ['keyword', 'status', 'message'],
    func: async (page, kwargs) => {
        if (!page) {
            throw new CommandExecutionError('Browser session required for twitter mute-word');
        }
        const keyword = parseKeyword(kwargs.keyword);

        await page.goto('https://x.com/settings/add_muted_keyword');
        await page.wait({ selector: '[data-testid="primaryColumn"]' }).catch(() => {});

        const result = await page.evaluate(`(async () => {
            const keyword = ${JSON.stringify(keyword)};
            let writeStarted = false;
            const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
            const visible = (node) => {
                if (!node) return false;
                const style = window.getComputedStyle ? window.getComputedStyle(node) : null;
                return !style || (style.visibility !== 'hidden' && style.display !== 'none');
            };
            const textOf = (node) => String(node?.innerText || node?.textContent || '').trim();
            const lowerTextOf = (node) => textOf(node).toLowerCase();
            const exactTextOf = (node) => lowerTextOf(node).replace(/\\s+/g, ' ');

View on GitHub (pinned to 49907e53dc)