jackwener/OpenCLI · error · ArgumentError
twitter profile username must be a valid Twitter/X handle
Error message
twitter profile username must be a valid Twitter/X handle
What it means
ArgumentError thrown during argument validation when a username was supplied to `twitter profile` but it cannot be normalized into a valid Twitter/X handle by normalizeTwitterScreenName (empty after stripping @, illegal characters, too long).
Source
Thrown at clis/twitter/profile.js:88
}
cli({
site: 'twitter',
name: 'profile',
access: 'read',
description: 'Fetch a Twitter user profile — bio, stats, etc. (defaults to the logged-in user when no username is given)',
domain: 'x.com',
strategy: Strategy.COOKIE,
browser: true,
args: [
{ name: 'username', type: 'string', positional: true, help: 'Twitter screen name (with or without @). Defaults to the logged-in user when omitted.' },
],
columns: ['screen_name', 'name', 'bio', 'location', 'url', 'followers', 'following', 'tweets', 'likes', 'verified', 'created_at'],
func: async (page, kwargs) => {
const rawUsername = String(kwargs.username ?? '').trim();
let username = normalizeTwitterScreenName(rawUsername);
if (rawUsername && !username) {
throw new ArgumentError('twitter profile username must be a valid Twitter/X handle', 'Example: opencli twitter profile @jack');
}
// If no username, 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) {
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?');
}
// Navigate directly to the user's profile page (gives us cookie context)View on GitHub (pinned to 49907e53dc)
Solutions
- Pass just the handle: `opencli twitter profile @jack` or `jack` (the @ is optional)
- If you have a profile URL, extract the path segment first (x.com/<handle> → <handle>)
- Trim surrounding whitespace/quotes from the argument in your script/shell
Example fix
// before
opencli twitter profile 'https://x.com/jack?foo=1'
// after
const handle = new URL(url).pathname.split('/')[1];
opencli twitter profile handle; Defensive patterns
Strategy: validation
Validate before calling
function normalizeHandle(raw) {
let h = String(raw ?? '').trim();
const m = h.match(/(?:x|twitter)\.com\/([A-Za-z0-9_]{1,15})/); // accept URLs
if (m) h = m[1];
h = h.replace(/^@/, '');
return /^[A-Za-z0-9_]{1,15}$/.test(h) ? h : null;
}
if (!normalizeHandle(input)) throw new Error('invalid Twitter handle'); Try / catch
try {
await opencli('twitter profile', { username });
} catch (e) {
if (e.name === 'ArgumentError' && /valid Twitter\/X handle/.test(e.message)) {
throw new Error(`Bad handle "${username}" — use @name or a 1-15 char alphanumeric/underscore name`);
}
throw e;
} Prevention
- Extract the handle from profile URLs before passing them
- Strip @, whitespace, and query strings
- Enforce the 1-15 char [A-Za-z0-9_] handle regex in your wrapper
- Omit the username entirely to auto-detect the logged-in user
When it happens
Trigger: `opencli twitter profile <bad>` where the raw string (after trim) is non-empty but normalizeTwitterScreenName returns falsy: e.g. 'https://x.com/jack/path' passed raw, '@', names with spaces or >15 chars, or non-ASCII handles.
Common situations: Pasting a full profile URL instead of the handle; including a trailing slash or query string; accidental whitespace/newline from shell quoting; passing an email or display name instead of the handle.
Related errors
- Invalid --from username: ${JSON.stringify(kwargs.from)}
- twitter search query is empty
- twitter search --limit must be a positive integer
- twitter tweet URL cannot be empty
- Invalid tweet URL: ${value}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/b1edb2987159d46a.
Report an issue: GitHub.