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
- Pass the bare handle (with or without @), e.g. opencli twitter following @elonmusk --limit 200.
- Strip URL prefixes if you have a profile link — use only the screen-name path segment.
- Quote the argument properly in your shell so spaces do not corrupt it.
- 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
- Pass bare handles, never full profile URLs or display names
- Quote positional args in the shell to avoid token concatenation
- Trim punctuation/newlines from user-supplied handles
- Normalize inputs (@-optional) before invoking the CLI
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
- ${label} must be a non-negative integer, got ${JSON.stringif
- limit must be a positive integer
- bilibili comment ${label} must be a positive integer
- bilibili comment message cannot be empty
- bilibili unfollow target cannot be empty
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/3d2b7590f67b03b1.
Report an issue: GitHub.