jackwener/OpenCLI · warning · EmptyResultError

twitter profile

Error message

twitter profile

What it means

EmptyResultError('twitter profile') thrown when rawResult.notFound is set — the UserByScreenName response indicated the screen name does not resolve to a user (Twitter returns success with data.user.result absent). It is the typed 'no such entity' outcome, distinct from auth or transport failures.

Source

Thrown at clis/twitter/profile.js:181

        if (!result) return {ok: false, notFound: true, error: 'User @' + screenName + ' not found'};
        return {ok: true, result};
      }
    `));
        if (!isPlainObject(rawResult)) {
            throw new CommandExecutionError('Twitter profile response payload is malformed');
        }
        if (!rawResult.ok) {
            // For HTTP errors, use fork's rich code mapping (429/401/403/404/5xx differentiation
            // from describeTwitterApiError); fall back to the plain message for non-HTTP failures
            // (fetch threw, JSON parse failed, payload malformed).
            const message = typeof rawResult.httpStatus === 'number'
                ? describeTwitterApiError('UserByScreenName', rawResult.httpStatus, rawResult.hint)
                : rawResult.error + (rawResult.hint ? ` (${rawResult.hint})` : '');
            if (rawResult.auth) {
                throw new AuthRequiredError('x.com', message);
            }
            if (rawResult.notFound) {
                throw new EmptyResultError('twitter profile', message);
            }
            throw new CommandExecutionError(message);
        }
        return mapTwitterProfileResult(rawResult.result, username);
    }
});

export const __test__ = { mapTwitterProfileResult };

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Verify the screen name spelling and that the account still exists by opening https://x.com/<username>
  2. Treat EmptyResultError as 'user not found' in your pipeline and skip the record instead of retrying
  3. Re-fetch the current handle from your source of truth if the account may have been renamed
  4. Check whether the profile is suspended/private; those cannot be fetched without following/access

Example fix

// before
const profile = await cli.run('twitter profile', { username: handle });
// after
try {
  const profile = await cli.run('twitter profile', { username: handle });
} catch (e) {
  if (e instanceof EmptyResultError) return skip(handle); // user does not exist
  throw e;
}
Defensive patterns

Strategy: try-catch

Type guard

function isEmptyResultError(e) {
  return e instanceof EmptyResultError || e.name === 'EmptyResultError';
}

Try / catch

try {
  return await cli.run('twitter profile', { username });
} catch (e) {
  if (e instanceof EmptyResultError) return null; // user does not exist
  throw e;
}

Prevention

When it happens

Trigger: Querying @username that does not exist, was renamed, or is suspended/protected so the GraphQL response has no user.result, making the in-page script return {ok:false, notFound:true}.

Common situations: Typo in the handle; account deleted or renamed since data was collected; querying suspended/banned accounts; region or age-gated profiles; scraping stale handle lists.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


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