jackwener/OpenCLI · error · CommandExecutionError
twitter_collection_limit_reached
twitter_collection_limit_reached
Error message
twitter_collection_limit_reached: pagination cannot prove completion
What it means
When a page pushes the collected posts to the configured limit, paginateCollection throws instead of stopping gracefully — because cutting off mid-pagination means the run cannot prove it reached the requested 'until' timestamp. The library treats an uncompleted collection as an error so callers never mistake a truncated set for a complete one.
Source
Thrown at clis/twitter/collection.js:270
};
}
async function paginateCollection({ until, limit, maxPages = MAX_USER_TWEETS_PAGES, fetchPage, wait }) {
const seen = new Set();
const seenCursors = new Set();
const posts = [];
let cursor = null;
let oldestSeenAt = null;
for (let pageIndex = 0; pageIndex < maxPages; pageIndex++) {
if (pageIndex > 0 && wait) await wait();
const payload = await fetchPage(cursor, USER_TWEETS_PAGE_SIZE);
if (payload?.error) {
throw new CommandExecutionError(`twitter_collection_request_error: UserTweets returned ${payload.error}`);
}
const [pagePosts, nextCursor] = parseCollectionPage(payload, seen);
for (const post of pagePosts) {
if (posts.length >= limit) {
throw new CommandExecutionError('twitter_collection_limit_reached: pagination cannot prove completion');
}
const createdAt = parseCreatedAt(post);
if (!oldestSeenAt || createdAt < oldestSeenAt) oldestSeenAt = createdAt;
posts.push(post);
if (createdAt <= until) {
return {
posts,
receipt: completedReceipt('time_boundary_reached', until, pageIndex + 1, oldestSeenAt),
};
}
}
if (!nextCursor) {
return {
posts,
receipt: completedReceipt('cursor_exhausted', until, pageIndex + 1, oldestSeenAt),
};
}
if (nextCursor === cursor || seenCursors.has(nextCursor)) {View on GitHub (pinned to 49907e53dc)
Solutions
- Increase the limit option so it exceeds the expected post count between now and 'until'.
- Move the 'until' cutoff closer to the present to reduce the number of posts that must be walked.
- Incremental collection: store the newest timestamp seen and use it as the next 'until' so each run walks fewer posts.
- Accept partial data explicitly (catch this error and keep posts accumulated so far, understanding completion is unproven).
- Raise maxPages in tandem with limit so pagination is actually allowed to reach the cutoff.
Example fix
// before
await cliRun({ limit: 100, until: sevenDaysAgo });
// after
await cliRun({ limit: 5000, until: oneHourAgo }); // limit large enough to cover posts since cutoff Defensive patterns
Strategy: validation
Validate before calling
const estimate = (now - until) / averageIntervalMs;
if (estimate > limit) {
console.warn(`limit ${limit} likely insufficient (~${Math.ceil(estimate)} posts expected)`);
} Try / catch
try {
const { posts, receipt } = await collection(...);
} catch (err) {
if (String(err.message).startsWith('twitter_collection_limit_reached')) {
// accept partial data explicitly, or rerun with larger limit / nearer until
} else throw err;
} Prevention
- Size limit above expected post volume between now and 'until'.
- Collect incrementally using the newest timestamp as the next 'until'.
- Raise maxPages together with limit.
- Never treat a thrown limit error as a complete collection.
- Tighten 'until' for high-volume accounts.
When it happens
Trigger: The user's limit (or default) is smaller than the number of posts published by the account since the 'until' cutoff — pagination would need to stop mid-run without reaching until.
Common situations: Collecting the last N hours from a very high-volume account with a small limit; reusing a limit tuned for one account against a far more prolific account; passing an 'until' far in the past so the whole timeline must be walked.
Related errors
- twitter_collection_page_guard_hit
- Twitter followers pagination exceeded ${MAX_PAGINATION_PAGES
- limit must be an integer between 1 and ${max}
- INVALID_LIMIT
- Jike notifications pagination exceeded ${MAX_PAGES} pages be
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/bf3a6156dfca6258.
Report an issue: GitHub.