jackwener/OpenCLI · error · Error

AUTH_REQUIRED: cannot resolve viewer secUid (login required)

Error message

AUTH_REQUIRED: cannot resolve viewer secUid (login required)

What it means

The following-list command must know the logged-in viewer's secUid before it can page /api/user/list. It first scans the page's __UNIVERSAL_DATA_FOR_REHYDRATION__ snapshot for the owner's secUid, then falls back to fetching /api/user/info. If both yield nothing, the session is not a usable logged-in session, so the library throws AUTH_REQUIRED instead of querying with a blank secUid.

Source

Thrown at clis/tiktok/following.js:77

      return false;
    });
    return found;
  }

  const universal = findUniversalData();
  let viewerSecUid = findViewerSecUid(universal);
  const msToken = getCookie('msToken');

  if (!viewerSecUid) {
    try {
      const me = await fetchJson('/api/user/info/?aid=' + aid + (msToken ? '&msToken=' + encodeURIComponent(msToken) : ''));
      viewerSecUid = String(me?.userInfo?.user?.secUid || me?.user?.secUid || me?.userInfo?.secUid || '').trim();
    } catch {
      // Fall through to typed AUTH_REQUIRED below.
    }
  }
  if (!viewerSecUid) {
    throw new Error('AUTH_REQUIRED: cannot resolve viewer secUid (login required)');
  }

  const dedup = new Map();
  let apiFailure = null;
  let cursor = 0;
  for (let page = 0; page < maxPages && dedup.size < limit; page += 1) {
    const params = new URLSearchParams({
      aid,
      scene: '21',
      secUid: viewerSecUid,
      count: String(pageSize),
      minCursor: String(cursor),
      maxCursor: '0',
    });
    if (msToken) params.set('msToken', msToken);
    try {
      const data = await fetchJson('/api/user/list/?' + params.toString());
      assertTikTokApiSuccess(data, 'user-list');

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Log into tiktok.com in the browser/session this command uses and confirm you see your own profile.
  2. Refresh/re-export the session cookies (ensure sessionid and friends-related cookies are present and not expired).
  3. Re-run the command on the /following page after a normal page load so __UNIVERSAL_DATA_FOR_REHYDRATION__ contains the owner user.
  4. Check that the /api/user/info fallback is reachable (no network/proxy blocking XHR) if cookies exist.
  5. If a TikTok UI change moved secUid out of these fields, update findViewerSecUid in clis/tiktok/following.js.

Example fix

// before: running with no/stale cookies
await followingCommand({ limit: 20 }); // AUTH_REQUIRED
// after: ensure a fresh logged-in session first
if (!(await isLoggedIn(page))) {
  await importCookies(page, freshSessionCookies); // includes sessionid
}
const rows = await followingCommand({ limit: 20 });
Defensive patterns

Strategy: validation

Validate before calling

// pre-check that the session carries login cookies before calling
const hasSession = await page.context().cookies().then(cs =>
  cs.some(c => c.name === 'sessionid' && c.value.length > 0));
if (!hasSession) throw new Error('refresh TikTok cookies before listing following');

Type guard

function hasViewerSecUid(payload) {
  return typeof payload?.secUid === 'string' && payload.secUid.length > 0;
}

Try / catch

try {
  rows = await followingCommand({ limit: 20 });
} catch (e) {
  if (/AUTH_REQUIRED/.test(e.message)) {
    await refreshSessionCookies(page); // re-export from a logged-in browser
    rows = await followingCommand({ limit: 20 });
  } else throw e;
}

Prevention

When it happens

Trigger: Running the tiktok following command without valid login cookies (sessionid missing/expired); the universal data snapshot has no isOwner user (logged-out or SSR variant); the /api/user/info fallback call fails or returns no secUid because TikTok redirected to a login wall.

Common situations: Stale exported cookies after TikTok rotated the session; loading tiktok.com from a fresh browser profile with no login; TikTok serving an anonymous rehydration payload to datacenter IPs; cookie strategy configured but cookies never imported.

Related errors


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