jackwener/OpenCLI · error · CommandExecutionError
Twitter UserMedia pagination reached the ${MAX_PAGINATION_PA
Error message
Twitter UserMedia pagination reached the ${MAX_PAGINATION_PAGES}-page safety cap before collecting ${limit} media items What it means
UserMedia pagination is capped at MAX_PAGINATION_PAGES iterations as a runaway-loop guard. If the loop ends having collected fewer items than --limit while the last response still advertised a next cursor, the command throws CommandExecutionError explaining the safety cap was reached before collecting the requested count.
Source
Thrown at clis/twitter/download.js:410
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);
await page.wait(3);
const items = unwrapBrowserResult(await page.evaluate(`View on GitHub (pinned to 49907e53dc)
Solutions
- Lower --limit to a value reachable within MAX_PAGINATION_PAGES pages
- Re-run the command; transient truncation may resolve on retry
- Raise MAX_PAGINATION_PAGES in the source if you maintain a fork and genuinely need deeper pagination
Example fix
// before opencli twitter download @jack --limit 500 // after opencli twitter download @jack --limit 100
Defensive patterns
Strategy: fallback
Validate before calling
const MAX_DELIVERABLE = MAX_PAGINATION_PAGES * ITEMS_PER_PAGE;
if (limit > MAX_DELIVERABLE) {
limit = MAX_DELIVERABLE;
console.warn(`Limit reduced to ${limit} due to pagination cap`);
} Try / catch
try {
return await cmd();
} catch (err) {
if (err.message.includes('safety cap')) {
return runWithLowerLimit(err); // retry with a smaller --limit
}
throw err;
} Prevention
- Choose --limit within what the page cap can deliver
- Incremental runs (resume with larger limits) instead of one huge request
- Expect this under rate-limited truncated pages and retry with a smaller limit
When it happens
Trigger: Requesting a large --limit (e.g. 500) on an account with abundant media where MAX_PAGINATION_PAGES pages of fetchCount-sized batches are insufficient, or pages returning fewer items than requested due to filtering/rate limiting.
Common situations: Setting --limit higher than what the page cap can deliver; Twitter returning truncated pages under rate limiting; duplicated items being deduplicated by `seen` so progress per page shrinks.
Related errors
- ${label} must be <= ${maxValue}
- coingecko limit must be <= 250 (per_page upper bound)
- Jike search pagination exceeded ${MAX_PAGES} pages before sa
- Sales Navigator messaging threads API reached the ${maxPages
- semanticscholar citations offset must be <= 9999
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/160b4536cdb6bb58.
Report an issue: GitHub.