jackwener/OpenCLI · error · ArgumentError

pypi downloads period "${value}" is invalid

Error message

pypi downloads period "${value}" is invalid

What it means

requirePeriod validates the `period` argument of the `pypi downloads` command against the allowed set {recent, overall} (case-insensitive, whitespace-trimmed, default 'recent'). Anything else throws ArgumentError `pypi downloads period "${value}" is invalid`. The library throws this to reject unsupported period values before any network call.

Source

Thrown at clis/pypi/downloads.js:17

// pypi downloads — fetch download counts for a single PyPI package via
// pypistats.org's public JSON API.
//
// Default endpoint is `/api/packages/<pkg>/recent` which returns last-day /
// last-week / last-month totals as a single row. Pass `--period overall` to
// hit `/api/packages/<pkg>/overall` for the full daily history (one row per
// day).
import { cli, Strategy } from '@jackwener/opencli/registry';
import { ArgumentError, EmptyResultError } from '@jackwener/opencli/errors';
import { PYPISTATS_BASE, pypiFetch, requirePackageName } from './utils.js';

const PERIODS = new Set(['recent', 'overall']);

function requirePeriod(value) {
    const s = String(value ?? 'recent').trim().toLowerCase();
    if (!PERIODS.has(s)) {
        throw new ArgumentError(
            `pypi downloads period "${value}" is invalid`,
            'Allowed values: recent (default — last day/week/month totals) or overall (full daily history).',
        );
    }
    return s;
}

cli({
    site: 'pypi',
    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)' },

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Use 'recent' for last day/week/month totals (the default)
  2. Use 'overall' for the full daily history
  3. Check the --period help text and correct the spelling
  4. Map any custom period your script uses to one of the two supported values before calling

Example fix

// before
const rows = await downloads({ name: 'requests', period: 'last_month' });
// after
const rows = await downloads({ name: 'requests', period: 'recent' }); // recent includes last_month
Defensive patterns

Strategy: validation

Validate before calling

// Validate period before invoking the command
function checkPeriod(p) {
  const s = String(p ?? 'recent').trim().toLowerCase();
  if (!['recent', 'overall'].includes(s)) {
    throw new Error(`period must be 'recent' or 'overall', got: ${p}`);
  }
  return s;
}

Type guard

function isPyPiPeriod(v) {
  return v === 'recent' || v === 'overall';
}

Try / catch

try {
  const rows = await downloads({ name, period });
} catch (e) {
  if (/period .* is invalid/.test(e.message)) {
    return downloads({ name, period: 'recent' }); // sensible default
  }
  throw e;
}

Prevention

When it happens

Trigger: Calling the downloads command with period values other than 'recent' or 'overall' — e.g. 'daily', 'month', 'all', 'last_week', or an empty-but-nondefault string.

Common situations: Assuming pypistats supports other windows (day/week/month as separate periods); typos like 'overal' or 'recnet'; passing flags from a different CLI's vocabulary; users copying period names from other stats tools.

Related errors


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