jackwener/OpenCLI · warning · EmptyResultError

pypi downloads

Error message

pypi downloads

What it means

When period is 'recent', the downloads command fetches pypistats /api/packages/<name>/recent and throws EmptyResultError 'pypi downloads' with detail `pypistats has no recent download data for "<name>"` if `body.data` is missing or all of last_day/last_week/last_month are null. The library throws this instead of rendering empty rows because there is genuinely no data to show.

Source

Thrown at clis/pypi/downloads.js:45

    name: 'downloads',
    access: 'read',
    description: 'PyPI download stats for a package (recent totals or full daily history)',
    domain: 'pypistats.org',
    strategy: Strategy.PUBLIC,
    browser: false,
    args: [
        { name: 'name', positional: true, required: true, help: 'PyPI package name (e.g. "requests", "pandas")' },
        { name: 'period', default: 'recent', help: 'recent (default — 1 row, last day/week/month) or overall (1 row per day)' },
    ],
    columns: ['rank', 'package', 'period', 'date', 'downloads'],
    func: async (args) => {
        const name = requirePackageName(args.name);
        const period = requirePeriod(args.period);
        if (period === 'recent') {
            const body = await pypiFetch(`${PYPISTATS_BASE}/api/packages/${encodeURIComponent(name)}/recent`, `pypi downloads ${name}`);
            const data = body?.data;
            if (!data || (data.last_day == null && data.last_week == null && data.last_month == null)) {
                throw new EmptyResultError('pypi downloads', `pypistats has no recent download data for "${name}".`);
            }
            return [
                { rank: 1, package: String(body.package ?? name), period: 'last_day', date: '', downloads: data.last_day != null ? Number(data.last_day) : null },
                { rank: 2, package: String(body.package ?? name), period: 'last_week', date: '', downloads: data.last_week != null ? Number(data.last_week) : null },
                { rank: 3, package: String(body.package ?? name), period: 'last_month', date: '', downloads: data.last_month != null ? Number(data.last_month) : null },
            ];
        }
        const body = await pypiFetch(`${PYPISTATS_BASE}/api/packages/${encodeURIComponent(name)}/overall?mirrors=false`, `pypi downloads ${name}`);
        const days = Array.isArray(body?.data) ? body.data : [];
        if (!days.length) {
            throw new EmptyResultError('pypi downloads', `pypistats has no overall download history for "${name}".`);
        }
        return days.map((row, i) => ({
            rank: i + 1,
            package: String(body.package ?? name),
            period: 'daily',
            date: String(row.date ?? ''),
            downloads: row.downloads != null ? Number(row.downloads) : null,

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Verify the package name is spelled correctly and exists on pypi.org
  2. Try --period overall to see if any daily history exists
  3. Wait and retry — pypistats aggregates on a delay for new packages
  4. Treat it as an expected empty result and handle EmptyResultError in your script

Example fix

// before
const rows = downloads('my-brand-new-pkg'); // EmptyResultError
// after
try {
  const rows = downloads('my-brand-new-pkg');
} catch (e) {
  if (e instanceof EmptyResultError) return []; // no data yet
  throw e;
}
Defensive patterns

Strategy: try-catch

Validate before calling

// Check the package exists on PyPI first
const res = await fetch('https://pypi.org/pypi/<name>/json');
if (!res.ok) throw new Error('Package does not exist on PyPI');

Type guard

function hasRecentData(body) {
  const d = body?.data;
  return Boolean(d) && ['last_day','last_week','last_month'].some(k => d[k] != null);
}

Try / catch

try {
  const rows = await downloads({ name, period: 'recent' });
} catch (e) {
  if (e instanceof EmptyResultError) {
    return []; // no data yet — treat as empty, not fatal
  }
  throw e;
}

Prevention

When it happens

Trigger: Querying a very new, unpublished, or near-zero-download package where pypistats has no recent totals; also triggered by a malformed response body lacking `data`.

Common situations: Checking a brand-new package minutes after publishing; a private/renamed package; typos in the package name hitting a package with no stats; pypistats lagging behind PyPI.

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