{"record":{"id":"66c774136592ba67","repo":"jackwener/OpenCLI","slug":"tiktok-returned-no-following-entries","errorCode":null,"errorMessage":"TikTok returned no following entries","messagePattern":"TikTok returned no following entries","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"warning","filePath":"clis/tiktok/following.js","lineNumber":140,"sourceCode":"`;\n}\n\nasync function listFollowing(page, args) {\n    const limit = requireLimit(args.limit, { fallback: DEFAULT_LIMIT, max: MAX_LIMIT });\n    await page.goto('https://www.tiktok.com/following', { waitUntil: 'load', settleMs: 5000 });\n    let rows;\n    try {\n        rows = await page.evaluate(buildFollowingScript(limit));\n    } catch (error) {\n        throwTikTokPageContextError(error, {\n            authMessage: 'TikTok requires login to read your following list',\n            emptyPattern: /No following entries/,\n            emptyTarget: 'tiktok following',\n            failureMessage: 'Failed to load TikTok following list',\n        });\n    }\n    if (!Array.isArray(rows) || rows.length === 0) {\n        throw new EmptyResultError('tiktok following', 'TikTok returned no following entries');\n    }\n    return rows;\n}\n\nexport const followingCommand = cli({\n    site: 'tiktok',\n    name: 'following',\n    access: 'read',\n    description: 'List accounts the logged-in user follows on TikTok via page-context APIs',\n    domain: 'www.tiktok.com',\n    strategy: Strategy.COOKIE,\n    browser: true,\n    args: [\n        { name: 'limit', type: 'int', default: DEFAULT_LIMIT, help: `Number of accounts (max ${MAX_LIMIT})` },\n    ],\n    columns: ['index', 'username', 'name', 'secUid', 'verified', 'followers', 'following', 'url'],\n    func: listFollowing,\n});","sourceCodeStart":122,"sourceCodeEnd":158,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/tiktok/following.js#L122-L158","documentation":"listFollowing's final safety net: even after the page script returns (or the page-context error mapper converts errors), if rows is not a non-empty array the library throws EmptyResultError('tiktok following', ...). It guarantees the command either returns real following rows or a typed empty-result error, never an empty success.","triggerScenarios":"The injected script returned null/undefined (e.g. an earlier error path was swallowed), or returned an empty array because TikTok's API yielded zero entries for the viewer.","commonSituations":"Account genuinely follows no one; a regression in the page script causing a non-array return; upstream API degrading to empty payloads (TikTok A/B changes to the user/list response shape).","solutions":["Check whether the account follows anyone; if not, this is expected and you should catch EmptyResultError.","Catch EmptyResultError and treat it as an empty list (rows = []) in your pipeline.","Update/upgrade the library if TikTok changed the response shape (userList vs user_list) so the script repopulates rows.","Re-run with a larger --limit or after re-logging in if it is transient.","Inspect rows returned from page.evaluate to distinguish null (script error) vs [] (true empty)."],"exampleFix":"// before\nconst rows = await followingCommand({ limit: 20 });\n// after\ntry {\n  rows = await followingCommand({ limit: 20 });\n} catch (e) {\n  if (e instanceof EmptyResultError) rows = [];\n  else throw e;\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":"function isEmptyResult(e) {\n  return e instanceof EmptyResultError;\n}","tryCatchPattern":"let rows = [];\ntry {\n  rows = await followingCommand({ limit });\n} catch (e) {\n  if (e instanceof EmptyResultError) rows = [];\n  else throw e;\n}","preventionTips":["Treat EmptyResultError as a normal empty list for accounts with no follows","Keep the library updated for TikTok response-shape changes","Distinguish null returns (script crash) from empty arrays (true empty) upstream","Verify with a browser session whether the following list is truly empty"],"tags":["tiktok","empty-result","emptyresulterror"],"backgroundTag":"empty-result-set","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T17:17:51.833Z"}