{"record":{"id":"d7d89dfd542100a4","repo":"jackwener/OpenCLI","slug":"twitter-likes","errorCode":null,"errorMessage":"twitter likes","messagePattern":"twitter likes","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"warning","filePath":"clis/twitter/likes.js","lineNumber":316,"sourceCode":"            const currentCount = useOutputFile ? outputCount : allTweets.length;\n            const remaining = fetchAll ? 100 : (limit - currentCount + 10);\n            const fetchCount = Math.min(100, remaining);\n            const apiUrl = buildLikesUrl(likesQueryId, userId, fetchCount, cursor);\n            const data = unwrapBrowserResult(await page.evaluate(`async () => {\n        const r = await fetch(${JSON.stringify(apiUrl)}, { headers: ${headers}, credentials: 'include' });\n        return r.ok ? await r.json() : { error: r.status };\n      }`));\n            if (data?.error) {\n                if ((useOutputFile ? outputCount : allTweets.length) === 0)\n                    throw new CommandExecutionError(describeTwitterApiError('Likes', data.error));\n                break;\n            }\n            lastRawResponse = data;\n            const hasInstructions = Array.isArray(data?.data?.user?.result?.timeline_v2?.timeline?.instructions)\n                || Array.isArray(data?.data?.user?.result?.timeline?.timeline?.instructions);\n            if (!hasInstructions) {\n                if (looksLikePrivateTwitterTimeline(data) && (useOutputFile ? outputCount : allTweets.length) === 0) {\n                    throw new EmptyResultError('twitter likes', `No likes returned for @${username} (Likes are private by default on X; only the account owner can view their own likes)`);\n                }\n                throw new CommandExecutionError('twitter_likes_protocol_error: missing Likes timeline instructions');\n            }\n            const { tweets, nextCursor } = parseLikes(data, seen);\n            if (useOutputFile) {\n                appendJsonlRows(outputFile, tweets);\n                outputCount += tweets.length;\n            }\n            else {\n                allTweets.push(...tweets);\n            }\n            const pageComplete = !nextCursor;\n            writeResumeFile(resumeFile, {\n                cursor: pageComplete ? null : nextCursor,\n                count: useOutputFile ? outputCount : allTweets.length,\n                tweets: useOutputFile ? undefined : allTweets,\n                updatedAt: new Date().toISOString(),\n                complete: pageComplete,","sourceCodeStart":298,"sourceCodeEnd":334,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/likes.js#L298-L334","documentation":"EmptyResultError with label 'twitter likes' thrown when the Likes API response has no timeline instructions and the payload looks like a private-timeline response while zero likes have been collected. Likes on X are only visible to the account owner, so the library distinguishes this expected privacy case from a generic protocol error.","triggerScenarios":"data has no data.user.result.timeline_v2.timeline.instructions (nor the legacy timeline path), looksLikePrivateTwitterTimeline(data) is true, and outputCount/allTweets.length === 0 at clis/twitter/likes.js:316.","commonSituations":"Fetching likes for an account other than the logged-in user (likes are private by default); the target user's likes are hidden; fetching your own likes while logged in as a different account.","solutions":["Log in as the account whose likes you want: only the owner can view their own Likes timeline.","Confirm you passed your own @username, not another user's.","If you own the account and still see this, re-authenticate (session may be downgraded to a logged-out/public view).","Accept the limitation: X no longer exposes likes publicly for other accounts."],"exampleFix":"// before\n$ cli twitter likes @some celebrity   // private timeline -> EmptyResultError\n// after\n$ cli twitter likes @my_own_handle    // run as the account owner, logged in","handlingStrategy":"try-catch","validationCode":"// only the account owner can see their likes: verify target === session user\nconst sessionUser = await getLoggedInHandle(page);\nif (normalize(sessionUser) !== normalize(username)) {\n  console.warn('Likes are private; only the account owner can fetch them.');\n}","typeGuard":"function sameUser(a, b) { return typeof a === 'string' && typeof b === 'string' && a.replace(/^@/, '').toLowerCase() === b.replace(/^@/, '').toLowerCase(); }","tryCatchPattern":"try {\n  await cli.twitter.likes({ username });\n} catch (e) {\n  if (e.name === 'EmptyResultError' && /private by default/.test(e.message)) {\n    console.error(`Likes for ${username} are private; log in as the owner.`);\n    return; // expected, not a bug\n  }\n  throw e;\n}","preventionTips":["Only fetch likes for the account you are logged in as","Warn users up front that X likes are owner-only","Check the session handle matches the requested handle before running","Do not treat this as a retryable failure"],"tags":["privacy","empty-result","twitter"],"backgroundTag":"empty-result","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}