jackwener/OpenCLI · error · Error

No videos found for @${username}

Error message

No videos found for @${username}

What it means

listUserVideos resolves the target account's secUid via the universal page bootstrap and, when needed, the /api/user/detail/ endpoint. If every source leaves secUid empty, the library cannot address the user's profile feed and throws this error. It means 'this username does not resolve to a TikTok account', not merely 'the account has no videos'.

Source

Thrown at clis/tiktok/user.js:95

  }

  const universal = findUniversalData();
  let secUid = '';
  const profileUser = findProfileUser(universal);
  if (profileUser) {
    secUid = String(profileUser.secUid || profileUser.sec_uid || '').trim();
  }

  const msToken = getCookie('msToken');
  if (!secUid) {
    const params = new URLSearchParams({ uniqueId: username, aid });
    if (msToken) params.set('msToken', msToken);
    const detail = await fetchJson('/api/user/detail/?' + params.toString());
    assertTikTokApiSuccess(detail, 'user-detail');
    secUid = String(detail?.userInfo?.user?.secUid || detail?.user?.secUid || '').trim();
  }
  if (!secUid) {
    throw new Error('No videos found for @' + username);
  }

  const dedup = new Map();
  for (const item of collectProfileItems(universal, secUid)) {
    addVideo(dedup, item, 'bootstrap');
  }

  let cursor = 0;
  let primaryFailure = null;
  for (let page = 0; page < maxPages && dedup.size < limit; page += 1) {
    const params = new URLSearchParams({
      secUid,
      count: String(pageSize),
      cursor: String(cursor),
      aid,
    });
    if (msToken) params.set('msToken', msToken);
    try {

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Verify the username exists by opening https://www.tiktok.com/@<username> in a browser; fix typos and pass the bare handle.
  2. Supply or refresh msToken (and cookies) so the /api/user/detail/ call succeeds.
  3. Check whether the API response shape changed and update the secUid extraction fields.
  4. Retry later if the profile API is rate-limited or temporarily failing.

Example fix

// before
await cli.tiktok.user('todoqst'); // typo -> secUid never resolves
// after: verify the handle first, then call
const handle = 'todoqs1'.replace(/^@+/, '');
if (!/^[A-Za-z0-9._-]+$/.test(handle)) throw new Error('bad handle');
await cli.tiktok.user(handle);
Defensive patterns

Strategy: validation

Validate before calling

// pre-check the handle resolves before calling the CLI
const handle = username.replace(/^@+/, '').trim();
if (!/^[A-Za-z0-9._-]+$/.test(handle)) throw new Error('invalid TikTok handle');
const probe = await fetch(`https://www.tiktok.com/@${handle}`, { redirect: 'manual' });
if (probe.status >= 300 && probe.status < 400) throw new Error(`@${handle} does not exist`);

Prevention

When it happens

Trigger: Passing a username that does not exist or was renamed; the user-detail API returning an error or an HTML login page instead of JSON (assertTikTokApiSuccess passing but userInfo.user.secUid absent); msToken missing/expired so the detail call is rejected; a typo'd or URL-encoded handle passed to the command.

Common situations: Scraping a deleted/banned/private account; TikTok API schema change moving secUid to a new field; rate limiting returning degraded responses without a hard failure; passing a full profile URL instead of the bare handle.

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/25bb8b4efdbbc4de. Report an issue: GitHub.