jackwener/OpenCLI · error · CommandExecutionError

Browser session required for twitter retweet

Error message

Browser session required for twitter retweet

What it means

The `twitter retweet` CLI command, like the reply command, requires an attached browser session. When page is undefined (no browser session), func throws this CommandExecutionError immediately, before parsing the tweet URL or navigating. Retweeting requires a logged-in browser context to click the retweet control.

Source

Thrown at clis/twitter/retweet.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: 'retweet',
    access: 'write',
    description: 'Retweet 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 retweet' },
    ],
    columns: ['status', 'message'],
    func: async (page, kwargs) => {
        if (!page)
            throw new CommandExecutionError('Browser session required for twitter retweet');
        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 retweet 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. Open/attach the browser session (and log in to X) before running `twitter retweet`.
  2. Make sure the previous automation step did not close the browser or the profile.
  3. In scripted/test usage, pass a valid page handle as the first argument to func.

Example fix

// before
opencli twitter retweet <tweet-url>            # no session
// after
opencli browser open --profile x-account
opencli twitter retweet <tweet-url>
Defensive patterns

Strategy: validation

Validate before calling

if (!session || !session.page) {
  throw new Error('Open/attach a browser session before twitter retweet');
}

Type guard

function hasBrowserSession(session) {
  return !!session && typeof session === 'object' && !!session.page && typeof session.page.goto === 'function';
}

Try / catch

try {
  await cli('twitter', 'retweet', { url: tweetUrl });
} catch (e) {
  if (String(e.message) === 'Browser session required for twitter retweet') {
    await cli('browser', 'open', { profile: 'x-account' });
    await cli('twitter', 'retweet', { url: tweetUrl });
  } else throw e;
}

Prevention

When it happens

Trigger: Invoking `twitter retweet <tweet-url>` without a browser session attached — no prior browser open/attach in the CLI session, or calling the retweet func directly with page undefined.

Common situations: Automations that call retweet before establishing the browser session; a crashed/closed automation browser dropping the session between commands; CI runs that skip the browser-attach step.

Related errors


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