jackwener/OpenCLI · warning · EmptyResultError
@${username} has no media
Error message
@${username} has no media What it means
After pagination completes with zero collected media items, the command throws EmptyResultError `@<username> has no media` with detail noting the account may be private, suspended, or simply have no media posts. This distinguishes a legitimately empty result from a failure.
Source
Thrown at clis/twitter/download.js:408
try {
const r = await fetch("${url}", { headers: ${headers}, credentials: 'include' });
if (!r.ok) return { ok: false, status: r.status };
return { ok: true, payload: await r.json() };
} catch (err) {
return { ok: false, error: err?.message ?? String(err) };
}
}`)));
const { items, nextCursor } = parseUserMedia(data, seen);
all.push(...items);
hasMorePages = Boolean(nextCursor);
if (!nextCursor) break;
if (nextCursor === cursor) {
throw new CommandExecutionError('Twitter UserMedia pagination returned the same cursor twice');
}
cursor = nextCursor;
}
if (all.length === 0) throw new EmptyResultError(`@${username} has no media`, 'Account may be private, suspended, or have no media posts');
if (all.length < limit && hasMorePages) {
throw new CommandExecutionError(`Twitter UserMedia pagination reached the ${MAX_PAGINATION_PAGES}-page safety cap before collecting ${limit} media items`);
}
const trimmed = all.slice(0, limit);
return downloadTwitterMedia(trimmed, {
output,
subdir: username,
cookies: formatCookieHeader(cookies),
browserCookies: cookies,
filenamePrefix: username,
ytdlpExtraArgs: ['--merge-output-format', 'mp4'],
});
}
async function downloadSingleTweet(page, tweetUrl, output) {
const target = parseTweetUrl(tweetUrl);
await page.goto(target.url);View on GitHub (pinned to 49907e53dc)
Solutions
- Verify the account has media posts by browsing https://x.com/<username>/media
- Ensure your browser session follows/can view the account if it is private
- If media visibly exists but none is found, update the CLI so parseUserMedia matches current response shape
Defensive patterns
Strategy: validation
Validate before calling
const hasMedia = await checkProfileMediaTab(username); // visit x.com/<u>/media first
if (!hasMedia) {
console.log('Account has no downloadable media; skipping');
return [];
} Try / catch
try {
await cmd();
} catch (err) {
if (err.name === 'EmptyResultError') {
return []; // legitimately no media — treat as success in pipelines
}
throw err;
} Prevention
- Check https://x.com/<username>/media in a browser before bulk runs
- Ensure your session can view the account if it is private
- Treat EmptyResultError as an empty result, not a hard failure, in automation
When it happens
Trigger: The target account exists (rest_id resolved) but every parsed UserMedia page yields zero media entities: account with no tweets containing media, protected account visible only to followers, suspended mid-flow, or parseUserMedia filters dropping everything.
Common situations: Querying a text-only account expecting images/videos; following a private account from a session that isn't authorized; account got suspended between lookup and media fetch; media parse logic outdated after x.com UI/GraphQL changes.
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 bookmarks found for the logged-in account
- Timeline is private or unavailable to the current X account;
- No device-follow notification tweets found.
- twitter download @${username}
- twitter download ${target.id}
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/1c6e2e96f1b9449a.
Report an issue: GitHub.