{"record":{"id":"b31aeb24da5746fa","repo":"jackwener/OpenCLI","slug":"timeline-is-private-or-unavailable-to-the-current","errorCode":null,"errorMessage":"Timeline is private or unavailable to the current X account; completion cannot be proven.","messagePattern":"Timeline is private or unavailable to the current X account; completion cannot be proven\\.","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"warning","filePath":"clis/twitter/collection.js","lineNumber":191,"sourceCode":"        author,\n        name: user?.legacy?.name || user?.core?.name || '',\n        text: tweet.note_tweet?.note_tweet_results?.result?.text || legacy.full_text || '',\n        likes: legacy.favorite_count || 0,\n        retweets: legacy.retweet_count || 0,\n        replies: legacy.reply_count || 0,\n        views: Number(tweet.views?.count) || 0,\n        is_retweet: Boolean(legacy.retweeted_status_result),\n        created_at: legacy.created_at || '',\n        url: `https://x.com/${author}/status/${tweet.rest_id}`,\n        ...extractMedia(legacy),\n        quoted_tweet: extractQuotedTweet(tweet),\n        relationship: extractRelationship(tweet),\n    };\n}\n\nfunction parseCollectionPage(payload, seen) {\n    if (looksLikePrivateTwitterTimeline(payload)) {\n        throw new EmptyResultError(\n            'twitter collection',\n            'Timeline is private or unavailable to the current X account; completion cannot be proven.',\n        );\n    }\n    const result = payload?.data?.user?.result;\n    if (!result || typeof result !== 'object') {\n        throw new CommandExecutionError('twitter_collection_protocol_error: missing UserTweets result');\n    }\n    const instructionSets = [\n        result.timeline_v2?.timeline?.instructions,\n        result.timeline?.timeline?.instructions,\n    ].filter(Array.isArray);\n    if (instructionSets.length === 0) {\n        throw new CommandExecutionError(\n            'twitter_collection_protocol_error: missing UserTweets timeline instructions',\n        );\n    }\n    const posts = [];","sourceCodeStart":173,"sourceCodeEnd":209,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/collection.js#L173-L209","documentation":"parseCollectionPage detects private/unavailable timelines via looksLikePrivateTwitterTimeline and throws an EmptyResultError before attempting to parse, because a private timeline yields no parseable page yet completeness of the collection cannot be proven. It signals that the authenticated X account cannot access the target's timeline at all.","triggerScenarios":"Requesting a user timeline whose payload matches the private-timeline heuristics — the target account is protected/private, suspended, blocked you, or the GraphQL response contains the standard unavailability structure.","commonSituations":"Collecting from a protected account you don't follow; account went private or was suspended mid-archive; authenticating with the wrong X account that lacks access; geo/withheld restrictions on the target.","solutions":["Authenticate as an X account that follows the private account (or confirm you're logged in as the intended user)","Verify the target handle is still active and public in a browser","Re-authenticate / refresh tokens if you believe you do have access","If the account is legitimately inaccessible, treat it as an empty result and stop — completion cannot be proven"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"function timelineLooksPrivate(payload) {\n  return looksLikePrivateTwitterTimeline(payload); // pre-check the same heuristic the CLI uses\n}\n// before collecting:\nif (timelineLooksPrivate(payload)) console.warn('target timeline is private/unavailable; aborting');","typeGuard":"function isAccessibleTimeline(payload) {\n  return !looksLikePrivateTwitterTimeline(payload)\n    && payload?.data?.user?.result != null\n    && typeof payload.data.user.result === 'object';\n}","tryCatchPattern":"try {\n  const posts = await collectTimeline(handle, { until, limit });\n} catch (err) {\n  if (String(err.message).includes('private or unavailable')) {\n    console.warn(`${handle}: timeline inaccessible to current account; skipping`);\n  } else throw err;\n}","preventionTips":["Verify the target account is public (or that your auth account follows it) before archiving","Confirm you're authenticated as the X account with access — wrong credentials are a common cause","Re-check account status (protected/suspended) when a previously public handle starts failing","Treat this as terminal for that handle: no retry will prove completion without access"],"tags":["twitter","privacy","auth","empty-result"],"backgroundTag":"private-timeline-unavailable","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}