jackwener/OpenCLI · error · CommandExecutionError
twitter_collection_invalid_timestamp
twitter_collection_invalid_timestamp
Error message
twitter_collection_invalid_timestamp: post ${post.id} What it means
parseCreatedAt validates each post's created_at field: it must be a non-empty string parseable to a valid Date. Posts without a usable timestamp cannot be compared against the 'until' cutoff, so completion of the collection can't be proven and the library throws this error naming the offending post id.
Source
Thrown at clis/twitter/collection.js:240
) {
nextCursor = value.value;
}
if (Array.isArray(value)) {
for (const item of value) visit(item);
return;
}
for (const child of Object.values(value)) {
if (child && typeof child === 'object') visit(child);
}
};
for (const instructions of instructionSets) visit(instructions);
return [posts, nextCursor];
}
function parseCreatedAt(post) {
const parsed = new Date(post.created_at);
if (typeof post.created_at !== 'string' || !post.created_at || Number.isNaN(parsed.getTime())) {
throw new CommandExecutionError(`twitter_collection_invalid_timestamp: post ${post.id}`);
}
return parsed;
}
function completedReceipt(stopReason, until, pagesFetched, oldestSeenAt) {
return {
completed: true,
stop_reason: stopReason,
requested_until: until.toISOString(),
pages_fetched: pagesFetched,
oldest_seen_at: oldestSeenAt ? oldestSeenAt.toISOString() : null,
};
}
async function paginateCollection({ until, limit, maxPages = MAX_USER_TWEETS_PAGES, fetchPage, wait }) {
const seen = new Set();
const seenCursors = new Set();
const posts = [];View on GitHub (pinned to 49907e53dc)
Solutions
- Skip or whitelist promoted/ad entries and tombstones in the visit() walker before calling parseCreatedAt.
- Log the offending post.id and its raw object to confirm which entry type lacks created_at.
- Add a fallback timestamp source (e.g. tweet.core.legacy.created_at or sort index) if X moved the field.
- Update the library if X changed the legacy payload shape.
- Retry pagination — transient timeline injections usually disappear on the next page fetch.
Example fix
// before
const createdAt = parseCreatedAt(post);
// after
if (!post?.created_at || Number.isNaN(new Date(post.created_at).getTime())) {
console.warn('skipping post without timestamp', post?.id);
continue;
}
const createdAt = parseCreatedAt(post); Defensive patterns
Strategy: type-guard
Validate before calling
const bad = posts.filter(p => typeof p?.created_at !== 'string' || !p.created_at || Number.isNaN(new Date(p.created_at).getTime()));
if (bad.length) console.warn('posts lacking valid created_at:', bad.map(p => p.id)); Type guard
function hasValidCreatedAt(post) {
return typeof post?.created_at === 'string' && post.created_at.length > 0
&& !Number.isNaN(new Date(post.created_at).getTime());
} Try / catch
try {
const createdAt = parseCreatedAt(post);
} catch (err) {
if (String(err.message).startsWith('twitter_collection_invalid_timestamp')) {
const id = String(err.message).split('post ')[1];
console.warn('skipping malformed post', id);
} else throw err;
} Prevention
- Filter promoted/ad/tombstone entries before timestamp parsing.
- Validate created_at is a parseable string for every entry you walk.
- Support alternate timestamp locations (tweet.core.legacy.created_at) as fallback.
- Keep the library updated when X renames legacy fields.
- Log offending post ids to identify which entry types lack timestamps.
When it happens
Trigger: A UserTweets entry whose tweet.legacy.created_at is missing, empty, or malformed (e.g. ad/promoted entries, tombstones reshaped into post objects, or X renaming legacy fields).
Common situations: Promoted/ad tweets injected into the timeline lacking legacy.created_at; X schema change renaming created_at; posts from retweets/quote cards with truncated legacy objects; account locale changes altering date format unexpectedly.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- twitter collection --until must be an RFC3339 timestamp
- ${label} must be a positive integer
- ${label} must be <= ${maxValue}
- Bilibili view API did not return pages[] for --page selectio
- 分P 序号超出范围:p=${pageNum}(该视频共 ${total} 集)
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/a176d25f605ef289.
Report an issue: GitHub.