{"record":{"id":"d36f467cef72bb16","repo":"jackwener/OpenCLI","slug":"twitter-following-user-cannot-be-empty","errorCode":null,"errorMessage":"twitter following user cannot be empty","messagePattern":"twitter following user cannot be empty","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/twitter/following.js","lineNumber":178,"sourceCode":"            await page.goto('https://x.com/home');\n            await page.wait({ selector: '[data-testid=\"primaryColumn\"]' });\n            // Bridge wraps primitive page.evaluate returns as { session, data:<value> };\n            // unwrap so the href string is usable downstream.\n            // NOTE: the function-literal form `() => ...` silently drops\n            // primitive return values through the bridge — only the template\n            // string form preserves the `data` field.\n            const href = unwrapBrowserResult(await page.evaluate(`() => {\n        const link = document.querySelector('a[data-testid=\"AppTabBar_Profile_Link\"]');\n        return link ? link.getAttribute('href') : null;\n      }`));\n            if (!href || typeof href !== 'string')\n                throw new AuthRequiredError('x.com', 'Could not detect logged-in user. Are you logged in?');\n            targetUser = normalizeScreenName(href);\n            if (!targetUser)\n                throw new AuthRequiredError('x.com', 'Could not detect logged-in user. Are you logged in?');\n        }\n        if (!targetUser) {\n            throw new ArgumentError('twitter following user cannot be empty', 'Example: opencli twitter following @elonmusk --limit 200');\n        }\n\n        const followingQueryId = await resolveTwitterQueryId(page, 'Following', FOLLOWING_QUERY_ID);\n        const userByScreenNameQueryId = await resolveTwitterQueryId(page, 'UserByScreenName', USER_BY_SCREEN_NAME_QUERY_ID);\n        const headers = {\n            'Authorization': `Bearer ${decodeURIComponent(TWITTER_BEARER_TOKEN)}`,\n            'X-Csrf-Token': ct0,\n            'X-Twitter-Auth-Type': 'OAuth2Session',\n            'X-Twitter-Active-User': 'yes',\n        };\n\n        // Get userId from screen_name\n        const userLookup = unwrapBrowserResult(await page.evaluate(async (url, headers) => {\n            const resp = await fetch(url, { headers, credentials: 'include' });\n            if (!resp.ok) return { error: resp.status };\n            const d = await resp.json();\n            return { userId: d.data?.user?.result?.rest_id || null };\n        }, buildUserByScreenNameQueryUrl(userByScreenNameQueryId, targetUser), headers));","sourceCodeStart":160,"sourceCodeEnd":196,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/following.js#L160-L196","documentation":"ArgumentError thrown by the `twitter following` command when no target user could be determined. The command requires either an explicit @screen_name argument or a resolvable logged-in user from the session; both were empty, so it refuses to run and shows a usage example.","triggerScenarios":"Invoking `opencli twitter following` with no positional user argument and no logged-in x.com session (or a session whose screen name could not be normalized), leaving targetUser falsy after all fallbacks.","commonSituations":"Forgetting the positional argument entirely; passing an argument that normalizeScreenName rejects (e.g. a full profile URL not handled, or 'me' without being logged in); combining empty arg with an unauthenticated browser.","solutions":["Pass the target screen name explicitly: `opencli twitter following @elonmusk --limit 200`","If you intended your own account, log into x.com in the CLI browser session so targetUser resolves","Check for typos in the argument (empty string, whitespace-only, or an unsupported format)","Run `opencli twitter following --help` to confirm the expected argument form"],"exampleFix":"// before\n$ opencli twitter following\n// after\n$ opencli twitter following @elonmusk --limit 200","handlingStrategy":"validation","validationCode":"function validateFollowingArgs(args) {\n  const user = (args[0] || '').trim();\n  if (!user || !/^@?[A-Za-z0-9_]{1,15}$/.test(user)) {\n    throw new Error('Usage: opencli twitter following @screenname --limit 200');\n  }\n  return user.startsWith('@') ? user : '@' + user;\n}","typeGuard":"function isValidScreenName(v) {\n  return typeof v === 'string' && /^@?[A-Za-z0-9_]{1,15}$/.test(v.trim());\n}","tryCatchPattern":"try {\n  await cli.following(normalizeScreenName(input));\n} catch (err) {\n  if (err.name === 'ArgumentError') {\n    console.error('Missing/invalid user. Example: opencli twitter following @elonmusk --limit 200');\n  } else throw err;\n}","preventionTips":["Always pass the positional @screen_name explicitly","Validate the handle matches Twitter's 1-15 char [A-Za-z0-9_] rule before invoking","If relying on the logged-in user default, confirm the session is authenticated first","Check `--help` output when scripting to keep argument forms correct"],"tags":["arguments","usage","twitter"],"backgroundTag":"missing-required-argument","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}