jackwener/OpenCLI · warning · EmptyResultError

No device-follow notification tweets found.

Error message

No device-follow notification tweets found.

What it means

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.

Source

Thrown at clis/twitter/device-follow.js:179

        }
        if (data?.errorKind === 'exception') {
            throw new CommandExecutionError(`Twitter device-follow fetch failed: ${data.detail || 'unknown error'}`);
        }
        if (data?.error) {
            if (data.error === 401 || data.error === 403) {
                throw new AuthRequiredError('x.com', `Twitter device-follow returned HTTP ${data.error}`);
            }
            throw new CommandExecutionError(describeTwitterApiError('device_follow', data.error));
        }
        const parsed = parseDeviceFollow(data, new Set());
        if (!parsed) {
            throw new CommandExecutionError('Twitter device-follow response was missing the expected timeline/globalObjects shape.');
        }
        if (parsed.malformedEntries > 0 || parsed.unmatchedTweetEntries > 0) {
            throw new CommandExecutionError('Twitter device-follow entries could not be joined to tweet/user objects.');
        }
        if (parsed.rows.length === 0) {
            throw new EmptyResultError('twitter device-follow', 'No device-follow notification tweets found.');
        }
        const rows = parsed.rows;
        const trimmed = rows.slice(0, limit);
        return applyTopByEngagement(trimmed, kwargs['top-by-engagement']);
    },
});

export const __test__ = {
    buildDeviceFollowUrl,
    extractEntries,
    joinEntryToTweet,
    shapeRow,
    parseDeviceFollow,
    parseLimit,
};

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Verify the account actually has device-follow notifications (check x.com notification settings)
  2. Try a different account known to have notifications
  3. Relax any filters/top-by-engagement options that could exclude all rows
  4. Treat it as an expected empty state and handle EmptyResultError separately from hard failures

Example fix

// before
cli twitter device-follow --limit 20  # EmptyResultError
// after
cli twitter device-follow --limit 50  # widen window, or handle empty as normal
Defensive patterns

Strategy: fallback

Validate before calling

// Confirm the account has device-follow notifications before treating as a failure
const hasNotifications = await checkXcomNotificationsExist(account);
if (!hasNotifications) return [];

Try / catch

try {
  rows = await cli.twitter.deviceFollow();
} catch (e) {
  if (e instanceof EmptyResultError) {
    rows = []; // empty is an expected outcome, not a failure
  } else throw e;
}

Prevention

When it happens

Trigger: 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.

Common situations: Running the command against a fresh or inactive account; expecting notifications that Twitter has already delivered/marked read; notification settings disabling device-follow alerts.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29). Data as JSON: /api/errors/78b6f232628cfe62. Report an issue: GitHub.