jackwener/OpenCLI · error · ArgumentError

npm downloads period "${value}" is invalid

Error message

npm downloads period "${value}" is invalid

What it means

requirePeriod falls back to this ArgumentError when the period string is neither one of the fixed keywords (last-day/last-week/last-month/last-year) nor a match for RANGE_PATTERN (YYYY-MM-DD:YYYY-MM-DD). The error message includes the offending value and a hint listing all accepted formats.

Source

Thrown at clis/npm/downloads.js:24

import { cli, Strategy } from '@jackwener/opencli/registry';
import { ArgumentError, EmptyResultError } from '@jackwener/opencli/errors';
import { NPM_API, npmFetch, requirePackageName } from './utils.js';

const FIXED_PERIODS = new Set(['last-day', 'last-week', 'last-month', 'last-year']);
const RANGE_PATTERN = /^(\d{4}-\d{2}-\d{2}):(\d{4}-\d{2}-\d{2})$/;

function requirePeriod(value) {
    const s = String(value ?? 'last-week').trim();
    if (FIXED_PERIODS.has(s)) return s;
    const m = RANGE_PATTERN.exec(s);
    if (m) {
        const [, start, end] = m;
        if (new Date(start) > new Date(end)) {
            throw new ArgumentError(`npm downloads period start ${start} is after end ${end}`);
        }
        return `${start}:${end}`;
    }
    throw new ArgumentError(
        `npm downloads period "${value}" is invalid`,
        'Use last-day / last-week (default) / last-month / last-year, or YYYY-MM-DD:YYYY-MM-DD.',
    );
}

cli({
    site: 'npm',
    name: 'downloads',
    access: 'read',
    description: 'Daily download counts for an npm package over a window',
    domain: 'api.npmjs.org',
    strategy: Strategy.PUBLIC,
    browser: false,
    args: [
        { name: 'name', positional: true, required: true, help: 'npm package name (e.g. "react", "@vercel/og")' },
        { name: 'period', default: 'last-week', help: 'last-day / last-week / last-month / last-year, or YYYY-MM-DD:YYYY-MM-DD' },
    ],
    columns: ['rank', 'package', 'day', 'downloads'],

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Use one of the exact keywords: last-day, last-week, last-month, last-year
  2. Use the strict range form YYYY-MM-DD:YYYY-MM-DD, e.g. 2024-01-01:2024-03-31
  3. Normalize relative inputs (e.g. '30d') to a concrete date range before calling the CLI
  4. Follow the hint embedded in the error message for accepted formats

Example fix

// before
--period last-30-days
// after
--period 2026-07-30:2026-08-29   # or --period last-month
Defensive patterns

Strategy: validation

Validate before calling

const FIXED = ['last-day','last-week','last-month','last-year'];
const RANGE = /^\d{4}-\d{2}-\d{2}:\d{4}-\d{2}-\d{2}$/;
if (!FIXED.includes(p) && !RANGE.test(p)) throw new Error(`period "${p}" invalid; use ${FIXED.join('/')} or YYYY-MM-DD:YYYY-MM-DD`);

Type guard

function isNpmPeriod(v){ return ['last-day','last-week','last-month','last-year'].includes(v) || /^\d{4}-\d{2}-\d{2}:\d{4}-\d{2}-\d{2}$/.test(v); }

Try / catch

try { await run(['npm-downloads', '--period', p]); }
catch (e) {
  if (e instanceof ArgumentError && /is invalid/.test(e.message)) {
    console.error(e.message, e.hint); // error carries a usage hint
    process.exitCode = 2;
  } else throw e;
}

Prevention

When it happens

Trigger: Passing periods such as '7d', 'week', '2024-01-01' (no end), '2024/01/01:2024/02/01' (slashes instead of dashes), 'last-week:' (malformed range), or an empty string after trimming.

Common situations: Using relative ranges like 'last-30-days' that the parser does not support; locale-formatted dates; CLI flag typo (--period last weak); scripts passing human-friendly strings straight through.

Related errors


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