jackwener/OpenCLI · error · ArgumentError

twitter collection username must be a valid Twitter/X handle

Error message

twitter collection username must be a valid Twitter/X handle

What it means

This is the same validation as the generic handle error but on the branch where no username was provided at all and `allowLoggedInDefault` is false for the `collection` command: `resolveUserTimelineContext` throws an ArgumentError because there is no valid handle and no permission to fall back to the logged-in user. The collection command requires either an explicit handle or an enabled logged-in default.

Source

Thrown at clis/twitter/user-timeline.js:170

}

export async function resolveUserTimelineContext(
    page,
    rawUsername,
    { allowLoggedInDefault = false, commandName = 'tweets' } = {},
) {
    const raw = String(rawUsername ?? '').trim();
    let username = normalizeTwitterScreenName(raw);
    if (raw && !username) {
        throw new ArgumentError(
            `twitter ${commandName} username must be a valid Twitter/X handle`,
            commandName === 'collection'
                ? 'Example: opencli twitter collection @jack --until 2026-07-23T00:00:00Z'
                : 'Example: opencli twitter tweets @jack --limit 20',
        );
    }
    if (!username && !allowLoggedInDefault) {
        throw new ArgumentError('twitter collection username must be a valid Twitter/X handle', 'Example: opencli twitter collection @jack --until 2026-07-23T00:00:00Z');
    }
    if (!username) {
        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;
        }`));
        if (!href || typeof href !== 'string') {
            throw new AuthRequiredError('x.com', 'Could not detect logged-in user. Are you logged in?');
        }
        username = normalizeTwitterScreenName(href);
        if (!username) {
            throw new AuthRequiredError('x.com', 'Could not detect logged-in user. Are you logged in?');
        }
    }

    const cookies = await page.getCookies({ url: 'https://x.com' });

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Provide a handle explicitly: `opencli twitter collection @jack --until 2026-07-23T00:00:00Z`.
  2. Ensure the shell variable holding the username is non-empty before invoking.
  3. If a logged-in default is intended, call resolveUserTimelineContext with `allowLoggedInDefault: true` (and have an active x.com session) so the profile link is used.
  4. Double-check the subcommand usage with --help to see whether it requires a username.

Example fix

// before
opencli twitter collection --until 2026-07-23T00:00:00Z        // missing username
// after
opencli twitter collection @jack --until 2026-07-23T00:00:00Z
Defensive patterns

Strategy: validation

Validate before calling

// collection requires an explicit handle unless allowLoggedInDefault is set
if (!username && !allowLoggedInDefault) {
  throw new Error('twitter collection requires a username, e.g. opencli twitter collection @jack --until 2026-07-23T00:00:00Z');
}

Type guard

function canResolveCollectionContext(args) {
  const hasHandle = /^[A-Za-z0-9_]{1,15}$/.test(String(args.username ?? '').trim().replace(/^@/, ''));
  return hasHandle || args.allowLoggedInDefault === true;
}

Try / catch

try {
  await cli.run(['twitter', 'collection', username, '--until', until]);
} catch (e) {
  if (/must be a valid Twitter\/X handle/.test(e.message) && !username) {
    console.error('Username is required for collection; pass @handle or enable the logged-in default');
  } else throw e;
}

Prevention

When it happens

Trigger: Running `opencli twitter collection` (or invoking resolveUserTimelineContext with `allowLoggedInDefault: false`) with an empty/missing username argument, so `username` is '' after normalization.

Common situations: Forgetting the positional username on the collection command; a shell variable expanding to empty (`$USER` unset); calling the shared helper programmatically without passing `allowLoggedInDefault: true`; confusing collection with `tweets`, which may allow the logged-in default.

Understand the failure class

Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.

Related errors


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