{"record":{"id":"78b6f232628cfe62","repo":"jackwener/OpenCLI","slug":"no-device-follow-notification-tweets-found","errorCode":null,"errorMessage":"No device-follow notification tweets found.","messagePattern":"No device-follow notification tweets found\\.","errorType":"exception","errorClass":"EmptyResultError","httpStatus":null,"severity":"warning","filePath":"clis/twitter/device-follow.js","lineNumber":179,"sourceCode":"        }\n        if (data?.errorKind === 'exception') {\n            throw new CommandExecutionError(`Twitter device-follow fetch failed: ${data.detail || 'unknown error'}`);\n        }\n        if (data?.error) {\n            if (data.error === 401 || data.error === 403) {\n                throw new AuthRequiredError('x.com', `Twitter device-follow returned HTTP ${data.error}`);\n            }\n            throw new CommandExecutionError(describeTwitterApiError('device_follow', data.error));\n        }\n        const parsed = parseDeviceFollow(data, new Set());\n        if (!parsed) {\n            throw new CommandExecutionError('Twitter device-follow response was missing the expected timeline/globalObjects shape.');\n        }\n        if (parsed.malformedEntries > 0 || parsed.unmatchedTweetEntries > 0) {\n            throw new CommandExecutionError('Twitter device-follow entries could not be joined to tweet/user objects.');\n        }\n        if (parsed.rows.length === 0) {\n            throw new EmptyResultError('twitter device-follow', 'No device-follow notification tweets found.');\n        }\n        const rows = parsed.rows;\n        const trimmed = rows.slice(0, limit);\n        return applyTopByEngagement(trimmed, kwargs['top-by-engagement']);\n    },\n});\n\nexport const __test__ = {\n    buildDeviceFollowUrl,\n    extractEntries,\n    joinEntryToTweet,\n    shapeRow,\n    parseDeviceFollow,\n    parseLimit,\n};\n","sourceCodeStart":161,"sourceCodeEnd":195,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/twitter/device-follow.js#L161-L195","documentation":"When the device-follow response parses and joins cleanly but contains zero rows, the command throws EmptyResultError scoped to 'twitter device-follow'. This is not a failure of the API call — it legitimately means no device-follow notification tweets were found for the account/query.","triggerScenarios":"The authenticated account has no device-follow notifications; --limit and any filters exclude everything; the account is new or has disabled the relevant notification types.","commonSituations":"Running the command against a fresh or inactive account; expecting notifications that Twitter has already delivered/marked read; notification settings disabling device-follow alerts.","solutions":["Verify the account actually has device-follow notifications (check x.com notification settings)","Try a different account known to have notifications","Relax any filters/top-by-engagement options that could exclude all rows","Treat it as an expected empty state and handle EmptyResultError separately from hard failures"],"exampleFix":"// before\ncli twitter device-follow --limit 20  # EmptyResultError\n// after\ncli twitter device-follow --limit 50  # widen window, or handle empty as normal\n","handlingStrategy":"fallback","validationCode":"// Confirm the account has device-follow notifications before treating as a failure\nconst hasNotifications = await checkXcomNotificationsExist(account);\nif (!hasNotifications) return [];","typeGuard":null,"tryCatchPattern":"try {\n  rows = await cli.twitter.deviceFollow();\n} catch (e) {\n  if (e instanceof EmptyResultError) {\n    rows = []; // empty is an expected outcome, not a failure\n  } else throw e;\n}","preventionTips":["Treat EmptyResultError as a normal empty state in scripts","Verify the account actually generates device-follow notifications","Widen --limit or remove restrictive filters if you expect data","Check x.com notification settings aren't disabling these alerts"],"tags":["empty-result","twitter","no-data"],"backgroundTag":"empty-result-set","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}