jackwener/OpenCLI · warning · EmptyResultError

twitter download ${target.id}

Error message

twitter download ${target.id}

What it means

The `twitter download <tweet-id>` command threw EmptyResultError because its in-page media extraction script returned an array with zero media items. The library throws this when the tweet parsed successfully but contains no downloadable media (images/videos), or when extraction silently found nothing on the live page. It deliberately distinguishes 'no data' from malformed payloads (which raise CommandExecutionError).

Source

Thrown at clis/twitter/download.js:453

          out.push({ type: 'image', url: src });
        });
        document.querySelectorAll('video').forEach(video => {
          const src = video.src || '';
          if (src) out.push({ type: 'video', url: src });
        });
        document.querySelectorAll('[data-testid="videoPlayer"]').forEach(player => {
          const tweetLink = player.closest('article')?.querySelector('a[href*="/status/"]');
          const href = tweetLink?.getAttribute('href') || '';
          if (href) out.push({ type: 'video-tweet', url: 'https://x.com' + href });
        });
        return out;
      })()
    `));
    if (!Array.isArray(items)) {
        throw new CommandExecutionError('Twitter tweet media extraction returned malformed payload');
    }
    if (items.length === 0) {
        throw new EmptyResultError(`twitter download ${target.id}`, 'No media found in the tweet');
    }
    const cookies = await page.getCookies({ domain: 'x.com' });
    const seen = new Set();
    const unique = items.filter((m) => {
        if (seen.has(m.url)) return false;
        seen.add(m.url);
        return true;
    }).map((m) => {
        return { ...m, tweet_id: target.id };
    });
    return downloadTwitterMedia(unique, {
        output,
        subdir: 'tweets',
        cookies: formatCookieHeader(cookies),
        browserCookies: cookies,
        filenamePrefix: 'tweet',
        ytdlpExtraArgs: ['--merge-output-format', 'mp4'],
    });

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Verify the tweet actually has images or video by opening https://x.com/<user>/status/<id> in a browser.
  2. Log into x.com in the connected browser session so protected/age-gated media is visible, then retry.
  3. Retry with a fresh page load (not a cached or limited view) in case media was not rendered.
  4. If media is visibly present but the error persists, the extraction selectors are likely stale — update the CLI or report the DOM change.

Example fix

// before
opencli twitter download 1234567890 // text-only tweet
// after
opencli twitter download 9876543210 // tweet with attached images/video
Defensive patterns

Strategy: validation

Validate before calling

// Extracted media array guard before consuming results
function hasMedia(items) {
  return Array.isArray(items) && items.length > 0 && items.every((m) => typeof m?.url === 'string');
}
// Run twitter download only for tweets you know embed media; pre-check the tweet
// (e.g. oEmbed or the profile page) to confirm media presence before invoking.

Type guard

function isMediaItem(m) {
  return typeof m === 'object' && m !== null && typeof m.url === 'string' && m.url.length > 0;
}

Try / catch

try {
  const rows = await twitterDownload(tweetId);
} catch (e) {
  if (e.code === 'EMPTY_RESULT') {
    // Tweet has no media — skip, don't retry
    logger.warn(`No media in tweet ${tweetId}, skipping`);
  } else throw e;
}

Prevention

When it happens

Trigger: Running `opencli twitter download <id>` on a tweet with no media attachments; extraction against a protected/deleted tweet where the DOM renders but yields no media nodes; X UI changes making the extractor's selectors miss media so items.length === 0.

Common situations: Passing a tweet ID for a text-only tweet; scraping a protected or age-gated account while logged out; X shipping a redesign that breaks extraction selectors; a rate-limited view of the tweet that omits media.

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/754946fcf00d2699. Report an issue: GitHub.