jackwener/OpenCLI · error · ArgumentError
twitter followers user cannot be empty
Error message
twitter followers user cannot be empty
What it means
A final defensive check after both the explicit user argument and profile-link resolution paths: if targetUser is still falsy, the command refuses to navigate to '/undefined/followers' and throws ArgumentError with a usage example. In practice this is hard to reach because the earlier branches throw first — it protects against normalizeScreenName returning a falsy value that slipped through both prior guards (e.g. rawUser empty and href branch somehow skipped normalization).
Source
Thrown at clis/twitter/followers.js:128
}
if (!targetUser) {
// Bridge wraps primitive page.evaluate returns as { session, data:<value> };
// unwrap so the href string is usable downstream.
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 find logged-in user profile link. Are you logged in?');
}
targetUser = normalizeScreenName(href);
if (!targetUser) {
throw new AuthRequiredError('x.com', 'Could not find logged-in user profile link. Are you logged in?');
}
}
if (!targetUser) {
throw new ArgumentError('twitter followers user cannot be empty', 'Example: opencli twitter followers @elonmusk --limit 100');
}
await page.installInterceptor('/Followers?');
const targetPath = `/${targetUser}/followers`;
await page.evaluate(`() => {
const targetPath = ${JSON.stringify(targetPath)};
window.history.pushState({}, '', targetPath);
window.dispatchEvent(new PopStateEvent('popstate', { state: {} }));
}`);
try {
await page.waitForCapture(CAPTURE_TIMEOUT_SECONDS);
}
catch {
throw new TimeoutError('twitter followers API capture', CAPTURE_TIMEOUT_SECONDS, 'No Followers response was observed after opening the followers list.');
}
const currentPath = unwrapBrowserResult(await page.evaluate('() => window.location.pathname'));
if (typeof currentPath !== 'string' || !currentPath.toLowerCase().endsWith('/followers')) {
throw new CommandExecutionError('SPA navigation to Twitter followers failed');View on GitHub (pinned to 49907e53dc)
Solutions
- Supply the user argument explicitly: opencli twitter followers @handle
- Ensure normalizeTwitterScreenName in shared.js returns a non-empty handle for valid input
- Verify you are calling the command with a non-empty, valid handle
Example fix
// before opencli twitter followers " " // after opencli twitter followers @elonmusk --limit 100
Defensive patterns
Strategy: validation
Validate before calling
const target = (raw ?? '').trim();
if (!/^@?[A-Za-z0-9_]{1,15}$/.test(target)) throw new Error('supply a handle, e.g. @elonmusk'); Type guard
const hasTarget = (s) => typeof s === 'string' && s.trim().length > 0;
Try / catch
try {
await opencli.twitter.followers(user);
} catch (err) {
if (err.message.includes('cannot be empty')) {
return opencli.twitter.followers(defaultHandle);
} else throw err;
} Prevention
- Never pass empty or whitespace-only user values
- Always pass an explicit handle in automated scripts
- Sanitize kwargs before invoking the command func
When it happens
Trigger: Reached only if kwargs.user is empty/whitespace AND the profile-link branch did not set targetUser (future code changes, or normalizeScreenName returning an empty string from an unexpected href without throwing at 4104/4105).
Common situations: Mostly defensive dead code today; can surface in forks or modified versions of the command where the earlier AuthRequiredError guards were removed or altered.
Related errors
- ${label} is required
- ${label} must be a positive integer
- ${label} must be <= ${maxValue}
- arxiv ${label} must be a positive integer
- arxiv ${label} must be <= ${maxValue}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/e8a00df532746127.
Report an issue: GitHub.