jackwener/OpenCLI · error · ArgumentError

twitter likes username must be a valid Twitter/X handle

Error message

twitter likes username must be a valid Twitter/X handle

What it means

The username argument is passed through normalizeTwitterScreenName, which strips/validates Twitter/X handle syntax. If a non-empty raw username yields no valid normalized handle, the value is not a legal screen name and ArgumentError is thrown, with an example command as remediation text.

Source

Thrown at clis/twitter/likes.js:226

        const useOutputFile = Boolean(fetchAll && outputFile);
        const maxPages = resolveMaxPages(kwargs, fetchAll);
        const topByEngagement = Number(kwargs['top-by-engagement'] || 0);
        if (useOutputFile && topByEngagement > 0) {
            throw new ArgumentError('--top-by-engagement cannot be combined with --output-file');
        }
        if (outputFile && !fetchAll) {
            throw new ArgumentError('--output-file requires --all');
        }
        if (resumeFile && !fetchAll) {
            throw new ArgumentError('--resume-file requires --all');
        }
        if (outputFile && !resumeFile) {
            throw new ArgumentError('--output-file requires --resume-file so partial archives remain resumable');
        }
        const rawUsername = String(kwargs.username ?? '').trim();
        let username = normalizeTwitterScreenName(rawUsername);
        if (rawUsername && !username) {
            throw new ArgumentError('twitter likes username must be a valid Twitter/X handle', 'Example: opencli twitter likes @jack --limit 20');
        }
        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 no username provided, detect the logged-in user.
        // Bridge wraps primitive page.evaluate returns as { session, data:<value> };
        // unwrap so the href string is usable downstream.
        if (!username) {
            // 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"]' });
            const href = unwrapBrowserResult(await page.evaluate(`() => {
        const link = document.querySelector('a[data-testid="AppTabBar_Profile_Link"]');
        return link ? link.getAttribute('href') : null;
      }`));

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Pass just the handle: `opencli twitter likes @jack --limit 20` (the @ prefix and alphanumerics/underscore, max 15 chars).
  2. Strip surrounding quotes/URL parts — extract the screen name from any profile URL first.
  3. Quote the argument in your shell so spaces don't split it, and check `set -x` output if scripting.

Example fix

// before
opencli twitter likes 'https://x.com/jack?foo=1'
// after
opencli twitter likes @jack --limit 20
Defensive patterns

Strategy: validation

Validate before calling

function isValidHandle(raw) {
  const h = raw.replace(/^@/, '');
  return /^[A-Za-z0-9_]{1,15}$/.test(h);
}
if (!isValidHandle(process.argv[3])) throw new Error('Pass a valid handle, e.g. @jack');

Type guard

function isTwitterScreenName(v) {
  return typeof v === 'string' && /^@?[A-Za-z0-9_]{1,15}$/.test(v);
}

Try / catch

try {
  await cli({ username: raw });
} catch (err) {
  if (err instanceof ArgumentError && /valid Twitter\/X handle/.test(err.message)) {
    // extract handle from URL or fix quoting, then retry
  }
}

Prevention

When it happens

Trigger: Passing something like `opencli twitter likes 'jack dorsey'` or `opencli twitter likes 'https://x.com/jack'` or a handle with invalid characters (!, spaces, >15 chars) as the positional username.

Common situations: Pasting a full profile URL instead of the handle; including trailing punctuation from copy-paste; shell quoting split the handle so the flag got a wrong value; typos like 'ja ck'.

Related errors


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