jackwener/OpenCLI · warning · EmptyResultError
TikTok returned an empty recommend feed
Error message
TikTok returned an empty recommend feed
What it means
After the explore script (with its built-in empty-result detection and retry wrapper) completed, the resolved value was either not an array or an empty array. listExploreVideos throws an EmptyResultError stating the recommend feed came back empty.
Solutions
- Confirm /explore shows videos when visited manually in the same profile
- Retry once after a pause — the recommend feed is sometimes transiently empty
- Check region/IP; switch to a region where the recommend feed is populated
- Update the library if TikTok changed the feed DOM/API structure
- Treat EmptyResultError as 'no feed data' in your pipeline, not a crash
Example fix
// before
const rows = await listExploreVideos(page, { limit: 20 });
// after
let rows;
try { rows = await listExploreVideos(page, { limit: 20 }); }
catch (e) {
if (e instanceof EmptyResultError) { await sleep(3000); rows = await listExploreVideos(page, { limit: 20 }); }
else throw e;
} Defensive patterns
Strategy: retry
Type guard
function isNonEmptyArray(v) { return Array.isArray(v) && v.length > 0; } Try / catch
try {
rows = await listExploreVideos(page, opts);
} catch (e) {
if (e instanceof EmptyResultError) {
await sleep(3000);
return listExploreVideos(page, opts); // recommend feed is sometimes transiently empty
}
throw e;
} Prevention
- Retry once or twice — the recommend feed can be transiently empty
- Verify the profile/IP can see the feed manually (login wall, region block)
- Treat EmptyResultError as no-data rather than a hard failure
- Update the library when TikTok changes feed markup
When it happens
Trigger: The explore/recommend extraction resolved to null/undefined/non-array, or to an array of length 0 even after the script's internal retry with emptyPattern /No videos found/ matching.
Common situations: TikTok's recommend feed is A/B-varied or region-locked to empty for the current IP, a login-gated feed, or the extraction script silently returning [] after TikTok changed feed markup.
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
- No videos found on /explore + suffix
- TikTok returned no notifications
- 1point3acres thread
- 1point3acres user
- amazon did not expose any ranked items
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/2b280381792a14dc.
Report an issue: GitHub.
Appendix: source
Thrown at clis/tiktok/explore.js:142
`;
}
async function listExploreVideos(page, args) {
const limit = requireLimit(args.limit, { fallback: DEFAULT_LIMIT, max: MAX_LIMIT });
await page.goto('https://www.tiktok.com/explore', { waitUntil: 'load', settleMs: 5000 });
let rows;
try {
rows = await page.evaluate(buildExploreScript(limit));
} catch (error) {
throwTikTokPageContextError(error, {
authMessage: 'TikTok requires browser access to load the explore feed',
emptyPattern: /No videos found/,
emptyTarget: 'tiktok explore',
failureMessage: 'Failed to load TikTok explore feed',
});
}
if (!Array.isArray(rows) || rows.length === 0) {
throw new EmptyResultError('tiktok explore', 'TikTok returned an empty recommend feed');
}
return rows;
}
export const exploreCommand = cli({
site: 'tiktok',
name: 'explore',
access: 'read',
description: 'Get trending TikTok videos from the recommend feed via page-context APIs',
domain: 'www.tiktok.com',
strategy: Strategy.COOKIE,
browser: true,
args: [
{ name: 'limit', type: 'int', default: DEFAULT_LIMIT, help: `Number of videos to return (max ${MAX_LIMIT})` },
],
columns: ['index', 'id', 'author', 'url', 'cover', 'title', 'desc', 'plays', 'likes', 'comments', 'shares', 'createTime'],
func: listExploreVideos,
});View on GitHub (pinned to 49907e53dc)