{"record":{"id":"d40d2205c79aa93f","repo":"jackwener/OpenCLI","slug":"twitter-following","errorCode":null,"errorMessage":"twitter following","messagePattern":"twitter following","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"warning","filePath":"clis/twitter/following.js","lineNumber":240,"sourceCode":"                    throw new AuthRequiredError('x.com', `Twitter following request failed (HTTP ${data.error})`);\n                throw new CommandExecutionError(describeTwitterApiError('Following', data.error));\n            }\n            lastRawResponse = data;\n            const { users, nextCursor } = parseFollowing(data);\n            for (const u of users) {\n                if (!seen.has(u.screen_name)) {\n                    seen.add(u.screen_name);\n                    allUsers.push(u);\n                }\n            }\n            if (!nextCursor || nextCursor === cursor)\n                break;\n            cursor = nextCursor;\n        }\n\n        if (allUsers.length === 0) {\n            if (looksLikePrivateTwitterTimeline(lastRawResponse)) {\n                throw new EmptyResultError('twitter following', `No following data returned for @${targetUser} (the target account may have set their following list to private)`);\n            }\n            throw new EmptyResultError('twitter following', `No following accounts found for @${targetUser}`);\n        }\n\n        return allUsers.slice(0, limit);\n    },\n});\n\nexport const __test__ = {\n    sanitizeQueryId,\n    buildFollowingUrl,\n    extractUser,\n    normalizeScreenName,\n    parseFollowing,\n};\n","sourceCodeStart":222,"sourceCodeEnd":256,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/following.js#L222-L256","documentation":"EmptyResultError with operation 'twitter following' thrown when the target account's following list appears private: the response matches looksLikePrivateTwitterTimeline, meaning Twitter returned an empty/timeline-like payload because the following list is not visible to you. The library surfaces this explicitly instead of reporting a silent empty result.","triggerScenarios":"Pagination completed (or first page) with zero users parsed AND lastRawResponse matches the private-timeline heuristic: requesting the following list of an account that hides it from non-followers, while your session is not an approved follower.","commonSituations":"Scraping a private/protected account's following list; viewing an account that restricts following visibility to mutuals/followers; being logged out (or as a non-follower) when the list is follower-only.","solutions":["Follow the target account from the CLI's logged-in x.com session, then re-run","Confirm in a browser at x.com/<name>/following whether the list is visible to your account","Use an account that has permission to view that following list","Accept the limitation: protected accounts' following lists are intentionally hidden"],"exampleFix":"// before: private following list, non-follower session\nError: twitter following — No following data returned for @privateuser (the target account may have set their following list to private)\n// after: follow the account with the session user first, then retry\n$ opencli twitter follow @privateuser && opencli twitter following @privateuser","handlingStrategy":"try-catch","validationCode":"// Only request following lists you can see\nasync function canViewFollowing(page, handle) {\n  return page.evaluate(async (h) => {\n    const r = await fetch(`https://x.com/${h}`, { credentials: 'include' });\n    return r.ok;\n  }, handle);\n}\nif (!(await canViewFollowing(page, target))) throw new Error('Account unavailable to your session');","typeGuard":"function isPrivateListError(err) {\n  return err && err.name === 'EmptyResultError' && /following list to private/.test(err.message);\n}","tryCatchPattern":"try {\n  const users = await cli.following(target);\n} catch (err) {\n  if (isPrivateListError(err)) {\n    console.warn(`${target} keeps their following list private; skipping.`);\n    return [];\n  }\n  throw err;\n}","preventionTips":["Follow the target account from the CLI session before requesting its following list","Check list visibility manually at x.com/<name>/following when in doubt","Skip protected/private accounts in batch scripts and log them for review","Don't treat this as a bug — visibility is enforced by the account owner"],"tags":["privacy","empty-result","twitter"],"backgroundTag":"empty-result-set","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}