jackwener/OpenCLI · error · ArgumentError

pypi package name "${value}" is not a valid distribution nam

Error message

pypi package name "${value}" is not a valid distribution name

What it means

ArgumentError thrown by requirePackageName when the name fails the PEP 508/426 normalized-name regex: only ASCII letters, digits, and '._-' separators, with no leading or trailing separator. PyPI rejects distribution names outside this grammar, so the CLI validates locally to avoid a wasted request.

Source

Thrown at clis/pypi/utils.js:16

// Shared helpers for the pypi adapters that hit the PyPI public JSON API
// (pypi.org/pypi/<pkg>/json) and pypistats.org for download stats.
import { ArgumentError, CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';

export const PYPI_BASE = 'https://pypi.org';
export const PYPISTATS_BASE = 'https://pypistats.org';
const UA = 'opencli-pypi-adapter (+https://github.com/jackwener/opencli)';

// PEP 508 / PEP 426 normalized name: letters, digits, "._-", with leading-letter rule relaxed by PyPI.
const PKG_NAME = /^[A-Za-z0-9]([A-Za-z0-9._-]*[A-Za-z0-9])?$/;

export function requirePackageName(value) {
    const s = String(value ?? '').trim();
    if (!s) throw new ArgumentError('pypi package name is required (e.g. "requests", "pandas")');
    if (!PKG_NAME.test(s)) {
        throw new ArgumentError(
            `pypi package name "${value}" is not a valid distribution name`,
            'PyPI accepts ASCII letters / digits / "._-" with no leading or trailing separator.',
        );
    }
    return s;
}

export async function pypiFetch(url, label) {
    let resp;
    try {
        resp = await fetch(url, { headers: { 'user-agent': UA, accept: 'application/json' } });
    }
    catch (err) {
        throw new CommandExecutionError(
            `${label} request failed: ${err?.message ?? err}`,
            'Check that pypi.org / pypistats.org are reachable from this network.',
        );
    }

View on GitHub (pinned to 49907e53dc)

Solutions

  1. Use the bare canonical distribution name, e.g. `pypi package requests`
  2. Strip extras/version specifiers from requirement strings before passing ('requests[security]>=2' → 'requests')
  3. Normalize to PEP 503 form (lowercase, collapse runs of -_. to a single '-') if the source name is irregular

Example fix

// before
await pypiPackage('requests[security]>=2.0');
// after
await pypiPackage('requests');
Defensive patterns

Strategy: validation

Validate before calling

const PKG_NAME = /^[A-Za-z0-9]([A-Za-z0-9._-]*[A-Za-z0-9])?$/;
if (!PKG_NAME.test(raw)) {
  throw new Error(`"${raw}" is not a valid PyPI distribution name`);
}

Type guard

function isValidPyPIName(v) {
  return typeof v === 'string' && /^[A-Za-z0-9]([A-Za-z0-9._-]*[A-Za-z0-9])?$/.test(v);
}

Try / catch

try {
  await pypiPackage(raw);
} catch (e) {
  if (/not a valid distribution name/i.test(e.message)) {
    console.error('Use the bare canonical name, e.g. requests (no extras/specifiers)');
  } else throw e;
}

Prevention

When it happens

Trigger: Calling `pypi package <name>` with names containing spaces, slashes, '@', non-ASCII characters, or names starting/ending with '.', '_' or '-' (e.g. 'my pkg', '-foo-', 'pkg/name').

Common situations: Pasting a full URL or 'pip install ...' string instead of the distribution name; typos with stray characters; importing a name from a requirements file that includes extras or version specifiers like 'requests[security]>=2.0'.

Understand the failure class

Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.

Related errors


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