jackwener/OpenCLI · error · CommandExecutionError

Could not find user @${username}

Error message

Could not find user @${username}

What it means

CommandExecutionError thrown when the UserByScreenName GraphQL lookup returns no user rest_id for the requested handle. The library resolves the handle to a numeric user ID before querying Likes; a missing rest_id means the account does not exist, is suspended, or is not resolvable with the current session.

Source

Thrown at clis/twitter/likes.js:269

        const likesQueryId = await resolveTwitterQueryId(page, 'Likes', LIKES_QUERY_ID);
        const userByScreenNameQueryId = await resolveTwitterQueryId(page, 'UserByScreenName', USER_BY_SCREEN_NAME_QUERY_ID);
        const headers = JSON.stringify({
            'Authorization': `Bearer ${decodeURIComponent(TWITTER_BEARER_TOKEN)}`,
            'X-Csrf-Token': ct0,
            'X-Twitter-Auth-Type': 'OAuth2Session',
            'X-Twitter-Active-User': 'yes',
        });
        // Get userId from screen_name
        const userId = unwrapBrowserResult(await page.evaluate(`async () => {
      const screenName = ${JSON.stringify(username)};
      const url = ${JSON.stringify(buildUserByScreenNameQueryUrl(userByScreenNameQueryId, username))};
      const resp = await fetch(url, { headers: ${headers}, credentials: 'include' });
      if (!resp.ok) return null;
      const d = await resp.json();
      return d.data?.user?.result?.rest_id || null;
    }`));
        if (!userId) {
            throw new CommandExecutionError(`Could not find user @${username}`);
        }
        const resumed = fetchAll ? readResumeFile(resumeFile, {
            source: 'likes',
            username,
            outputFile: useOutputFile ? outputFile : null,
        }) : null;
        if (useOutputFile && resumed && resumed.count > 0 && !fs.existsSync(outputFile)) {
            throw new CommandExecutionError(`Twitter likes output file is missing for resume state: ${outputFile}`);
        }
        if (useOutputFile && !resumed && fs.existsSync(outputFile)) {
            throw new ArgumentError(`Refusing to overwrite existing Twitter likes output file: ${outputFile}`);
        }
        const allTweets = useOutputFile ? [] : (resumed?.tweets ? [...resumed.tweets] : []);
        const jsonlState = useOutputFile ? loadJsonlArchiveState(outputFile) : null;
        const seen = useOutputFile
            ? jsonlState.seen
            : new Set(allTweets.map((tweet) => tweet?.id).filter(Boolean));
        if (useOutputFile && resumed && jsonlState.count !== resumed.count) {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Check the @username for typos and confirm the account exists by opening https://x.com/<username>.
  2. If the account was renamed, use the current handle.
  3. Re-authenticate: a stale session can make the lookup return an empty user result.
  4. If the account is suspended or deactivated, the error is expected; no fix exists.

Example fix

// before
$ cli twitter likes @joohn_doe
// after
$ cli twitter likes @john_doe   // corrected handle
Defensive patterns

Strategy: validation

Validate before calling

const handle = username.replace(/^@/, '');
if (!/^[A-Za-z0-9_]{1,15}$/.test(handle)) {
  throw new Error(`Invalid Twitter handle: ${username}`);
}

Type guard

function isValidHandle(u) { return typeof u === 'string' && /^@?[A-Za-z0-9_]{1,15}$/.test(u); }

Try / catch

try {
  await cli.twitter.likes({ username });
} catch (e) {
  if (/Could not find user @/.test(e.message)) {
    console.error(`Handle '${username}' not found; verify it exists at https://x.com/${username.replace('@','')}`);
  } else throw e;
}

Prevention

When it happens

Trigger: fetchUserByScreenName (in-page fetch of the UserByScreenName GraphQL endpoint) returns resp.ok but d.data.user.result.rest_id is falsy, so clis/twitter/likes.js:269 throws `Could not find user @${username}`.

Common situations: Typo in the @username passed on the command line; the account was renamed or deleted; the account is suspended/locked; running against a handle whose visibility changed (protected/deactivated).

Understand the failure class

Background: "User not found", "Invalid user", and "does not exist": what missing-user lookup errors mean across Rocket.Chat, LiteLLM, Phabricator, rustfs, and pnpm — this error's family across 10 libraries.

Related errors


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