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
- Verify the package name is spelled correctly and exists on pypi.org
- Try --period overall to see if any daily history exists
- Wait and retry — pypistats aggregates on a delay for new packages
- 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
- Verify the package name on pypi.org before querying stats
- Expect empty stats for very new or zero-download packages
- Fall back to --period overall when recent data is missing
- Handle EmptyResultError explicitly in scripts rather than crashing
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
- No trains found from ${fromStation.name} to ${toStation.name
- NO_DATA
- No Wayback snapshots for "${target}".
- Chess.com has no game archives for ${username}
- Chess.com has games archives for ${username} but no games in
AI-assisted analysis of jackwener/OpenCLI@49907e53dc (2026-08-29).
Data as JSON: /api/errors/e7fff85d208b2dba.
Report an issue: GitHub.