jackwener/OpenCLI · error · ArgumentError

twitter following user must be a valid Twitter/X handle

Error message

twitter following user must be a valid Twitter/X handle

What it means

ArgumentError thrown when the positional user argument is supplied but cannot be normalized to a valid Twitter/X screen name via normalizeScreenName. The command only validates when a non-empty raw user string was given; if normalization yields an empty string the argument is rejected with an example usage hint.

Source

Thrown at clis/twitter/following.js:148

        {
            name: 'user',
            positional: true,
            type: 'string',
            required: false,
            help: 'Twitter/X handle (with or without @). Omit to fetch the accounts the currently logged-in user follows.',
        },
        { name: 'limit', type: 'int', default: 50, help: 'Maximum number of following rows to return (default 50). Must be a positive integer.' },
    ],
    columns: ['screen_name', 'name', 'bio', 'followers'],
    func: async (page, kwargs) => {
        const limit = kwargs.limit === undefined || kwargs.limit === null ? 50 : Number(kwargs.limit);
        if (!Number.isInteger(limit) || limit <= 0) {
            throw new ArgumentError('twitter following --limit must be a positive integer', 'Example: opencli twitter following @elonmusk --limit 200');
        }
        const rawUser = String(kwargs.user ?? '').trim();
        let targetUser = normalizeScreenName(rawUser);
        if (rawUser && !targetUser) {
            throw new ArgumentError('twitter following user must be a valid Twitter/X handle', 'Example: opencli twitter following @elonmusk --limit 200');
        }

        const cookies = await page.getCookies({ url: 'https://x.com' });
        const ct0 = cookies.find((c) => c.name === 'ct0')?.value || null;
        if (!ct0)
            throw new AuthRequiredError('x.com', 'Not logged into x.com (no ct0 cookie)');

        if (!targetUser) {
            // Force a navigation to the home surface so the AppTabBar sidebar
            // is rendered; the framework pre-nav lands on bare x.com which
            // does not always expose AppTabBar_Profile_Link.
            await page.goto('https://x.com/home');
            await page.wait({ selector: '[data-testid="primaryColumn"]' });
            // Bridge wraps primitive page.evaluate returns as { session, data:<value> };
            // unwrap so the href string is usable downstream.
            // NOTE: the function-literal form `() => ...` silently drops
            // primitive return values through the bridge — only the template
            // string form preserves the `data` field.

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass the bare handle (with or without @), e.g. opencli twitter following @elonmusk --limit 200.
  2. Strip URL prefixes if you have a profile link — use only the screen-name path segment.
  3. Quote the argument properly in your shell so spaces do not corrupt it.
  4. Trim stray punctuation/newlines from the value before invoking.

Example fix

// before
opencli twitter following https://x.com/elonmusk --limit 200
// after
opencli twitter following @elonmusk --limit 200
Defensive patterns

Strategy: validation

Validate before calling

const isValidHandle = (h) => typeof h === 'string' && /^@?[A-Za-z0-9_]{1,15}$/.test(h.trim());
if (rawUser && !isValidHandle(rawUser)) {
  throw new Error(`'${rawUser}' is not a valid Twitter/X handle; pass e.g. @elonmusk`);
}

Type guard

const isValidHandle = (h) => typeof h === 'string' && /^@?[A-Za-z0-9_]{1,15}$/.test(h.trim());

Try / catch

import { ArgumentError } from '@jackwener/opencli/errors';
try {
  rows = await opencli.twitter.following(rawUser, { limit });
} catch (e) {
  if (e instanceof ArgumentError && /valid Twitter\/X handle/.test(e.message)) {
    // e.g. caller passed a profile URL — extract the screen-name segment and retry
    const handle = extractHandleFromInput(rawUser);
    rows = await opencli.twitter.following(handle, { limit });
  } else throw e;
}

Prevention

When it happens

Trigger: Calling opencli twitter following with a user argument containing invalid characters (spaces, non-handle symbols beyond @, over-length names), e.g. 'opencli twitter following "elon musk"' or 'opencli twitter following https://x.com/some/path'.

Common situations: Passing a full profile URL instead of a handle; including display name instead of @handle; extra shell tokens being concatenated into the positional arg; trailing punctuation from copy-paste (e.g. '@elonmusk,').

Related errors


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