jackwener/OpenCLI · error · EmptyResultError

twitter followers

Error message

twitter followers

What it means

EmptyResultError with command id 'twitter followers' thrown when the target account's follower data appears to indicate a private/restricted timeline. looksLikePrivateTwitterTimeline(lastRawResponse) matched heuristics on the last raw GraphQL payload, so the message specifically warns the account may have restricted its followers list rather than simply having none.

Source

Thrown at clis/twitter/followers.js:198

            await page.autoScroll({ times: 1, delayMs: 500 });
            try {
                await page.waitForCapture(CAPTURE_TIMEOUT_SECONDS);
            }
            catch {
                throw new TimeoutError('twitter followers pagination', CAPTURE_TIMEOUT_SECONDS, `Twitter returned a continuation cursor after ${allFollowers.length} rows, but the next Followers response was not observed.`);
            }
            await consumeCaptured();
            pages++;
            if (allFollowers.length === beforeCount && cursor === beforeCursor) {
                throw new CommandExecutionError('Twitter followers pagination repeated a cursor without returning new users');
            }
        }
        if (allFollowers.length < limit && cursor && pages >= MAX_PAGINATION_PAGES) {
            throw new CommandExecutionError(`Twitter followers pagination exceeded ${MAX_PAGINATION_PAGES} pages before cursor exhaustion`);
        }
        if (allFollowers.length === 0) {
            if (looksLikePrivateTwitterTimeline(lastRawResponse)) {
                throw new EmptyResultError('twitter followers', `No follower data returned for @${targetUser} (the target account may have set their followers list to private)`);
            }
            throw new EmptyResultError('twitter followers', `No followers found for @${targetUser}`);
        }
        return allFollowers.slice(0, limit);
    }
});

export const __test__ = {
    extractFollower,
    normalizeScreenName,
    parseFollowers,
    twitterGraphqlError,
};

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Verify the target account in a browser — if it is protected, its followers list is genuinely unavailable; use a different target.
  2. Confirm you are logged in with a valid x.com session (ct0 cookie) that can view that account.
  3. Re-run later in case the account temporarily restricted visibility.
  4. Do not retry blindly — this is a deterministic access restriction, not a transient failure.
Defensive patterns

Strategy: fallback

Validate before calling

// Pre-check the account's visibility in a browser or via a public profile endpoint before scraping followers
const isProtected = await checkAccountProtected(targetHandle); // your own helper
if (isProtected) throw new Error(`@${targetHandle} protects its followers list; scraping will fail`);

Try / catch

import { EmptyResultError } from '@jackwener/opencli/errors';
try {
  rows = await opencli.twitter.followers(user, { limit });
} catch (e) {
  if (e instanceof EmptyResultError && /private/.test(e.message)) {
    return []; // expected: account restricts followers
  }
  throw e;
}

Prevention

When it happens

Trigger: Pagination ended with allFollowers.length === 0 and the last raw Followers GraphQL response matched the private-timeline heuristics — the target account protects its followers list, or X returned an access-restricted timeline shell instead of user entries.

Common situations: Scraping a protected/private X account's followers; an account that switched to protected mode since you last scraped it; X serving a restricted response to sessions without sufficient trust; mistakenly targeting a suspended/limited account.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/9965d17ba6eec722. Report an issue: GitHub.