jackwener/OpenCLI · error · CommandExecutionError

Browser session required for twitter unretweet

Error message

Browser session required for twitter unretweet

What it means

`twitter unretweet` is a browser-only (Strategy.UI, browser: true) command; its func receives a live `page` from the registry. When there is no active browser session, `page` is falsy and this CommandExecutionError is thrown immediately at the top of func, before any navigation or page interaction. No state on x.com is modified.

Source

Thrown at clis/twitter/unretweet.js:19

import { CommandExecutionError, TimeoutError } from '@jackwener/opencli/errors';
import { cli, Strategy } from '@jackwener/opencli/registry';
import { parseTweetUrl, buildTwitterArticleScopeSource } from './shared.js';

cli({
    site: 'twitter',
    name: 'unretweet',
    access: 'write',
    description: 'Undo a retweet on a specific tweet',
    domain: 'x.com',
    strategy: Strategy.UI,
    browser: true,
    args: [
        { name: 'url', type: 'string', required: true, positional: true, help: 'The URL of the tweet to unretweet' },
    ],
    columns: ['status', 'message'],
    func: async (page, kwargs) => {
        if (!page)
            throw new CommandExecutionError('Browser session required for twitter unretweet');
        const target = parseTweetUrl(kwargs.url);
        await page.goto(target.url);
        await page.wait({ selector: '[data-testid="primaryColumn"]' });
        const result = await page.evaluate(`(async () => {
        let writeStarted = false;
        try {
            ${buildTwitterArticleScopeSource(target.id)}
            // Poll for the tweet to render. State probes scoped to the article
            // matching the requested status id — bare querySelector on a
            // conversation page would silently grab the first article (e.g.
            // the parent tweet) and unretweet the wrong one.
            let attempts = 0;
            let retweetBtn = null;
            let unretweetBtn = null;
            let targetArticle = null;

            while (attempts < 20) {
                targetArticle = findTargetArticle();

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Ensure a browser session is running and logged into x.com, then re-run `opencli twitter unretweet <tweet-url>`.
  2. Configure a browser-capable (headless or headed) environment if running in CI.
  3. Restart the CLI if the browser session died mid-run.
  4. When embedding, pass a valid page/session object to the command rather than undefined.

Example fix

// before
opencli twitter unretweet https://x.com/user/status/123  // no session -> error
// after
opencli browser start
opencli twitter unretweet https://x.com/user/status/123
Defensive patterns

Strategy: validation

Validate before calling

// ensure browser session before unretweet
const page = await session.getPage();
if (!page) await startBrowserSession();
return runCommand('twitter unretweet', { url: tweetUrl });

Type guard

function hasBrowserPage(page) {
  return typeof page === 'object' && page !== null &&
    typeof page.goto === 'function' && typeof page.evaluate === 'function';
}

Try / catch

try {
  await cli.run(['twitter', 'unretweet', tweetUrl]);
} catch (e) {
  if (/Browser session required/.test(e.message)) {
    await startBrowserSession();
    await cli.run(['twitter', 'unretweet', tweetUrl]);
  } else throw e;
}

Prevention

When it happens

Trigger: Running `opencli twitter unretweet <url>` without a browser session attached: browser not started, running in non-browser mode, browser crashed, or calling func programmatically with page undefined.

Common situations: CI environments with no browser configured; user closed the managed browser window; fresh install where the browser binary/profile is not set up; invoking the command through the registry API without session initialization.

Related errors


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