jackwener/OpenCLI · error · CommandExecutionError

Browser session required for twitter reply

Error message

Browser session required for twitter reply

What it means

The `twitter reply` CLI command requires an attached browser session (an already-logged-in page), which the runtime passes as `page`. When the command runs without a browser session, func receives page === undefined and the command immediately throws this CommandExecutionError before touching Twitter. The reply flow cannot work headlessly without a logged-in browser context.

Source

Thrown at clis/twitter/reply.js:263

cli({
    site: 'twitter',
    name: 'reply',
    access: 'write',
    description: 'Reply to a specific tweet, optionally with a local or remote image',
    domain: 'x.com',
    strategy: Strategy.UI, // Uses the UI directly to input and click post
    browser: true,
    args: [
        { name: 'url', type: 'string', required: true, positional: true, help: 'The URL of the tweet to reply to' },
        { name: 'text', type: 'string', required: true, positional: true, help: 'The text content of your reply' },
        { name: 'image', help: 'Optional local image path to attach to the reply' },
        { name: 'image-url', help: 'Optional remote image URL to download and attach to the reply' },
    ],
    columns: ['status', 'message', 'text', 'url'],
    func: async (page, kwargs) => {
        if (!page)
            throw new CommandExecutionError('Browser session required for twitter reply');
        if (kwargs.image && kwargs['image-url']) {
            throw new CommandExecutionError('Use either --image or --image-url, not both.');
        }
        let localImagePath;
        let cleanupDir;
        try {
            if (kwargs.image) {
                localImagePath = resolveImagePath(kwargs.image);
            } else if (kwargs['image-url']) {
                const downloaded = await downloadRemoteImage(kwargs['image-url']);
                localImagePath = downloaded.absPath;
                cleanupDir = downloaded.cleanupDir;
            }
            // Dedicated composer is normally more reliable than the inline
            // tweet page reply box, but X occasionally leaves that route on the
            // Home timeline behind a loading dialog. openReplyComposer falls
            // back to the target tweet's visible Reply action.
            const composer = await openReplyComposer(page, kwargs.url);

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Start or attach a browser session (e.g. the CLI's browser open/attach command) before running `twitter reply`.
  2. Ensure the automation browser is logged into the X account that should post the reply.
  3. If scripting, pass a page/session handle to func instead of undefined.

Example fix

// before
opencli twitter reply --url <tweet-url> --text "hi"
// after
opencli browser open --profile x-account
opencli twitter reply --url <tweet-url> --text "hi"
Defensive patterns

Strategy: validation

Validate before calling

// Guard in your wrapper before invoking the command:
if (!session || !session.page) {
  throw new Error('Open/attach a browser session before twitter reply');
}

Type guard

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

Try / catch

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

Prevention

When it happens

Trigger: Invoking `twitter reply ...` outside a browser-session context — e.g. running the CLI without first starting/attaching the browser session the registry expects, or calling the func programmatically with page omitted.

Common situations: Running the command in a fresh environment before `open`/browser attach; a wrapper script that lost the session between commands; calling the command module directly in tests without a page fixture.

Related errors


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