{"record":{"id":"bdf028433bb9d018","repo":"jackwener/OpenCLI","slug":"pypi-package-name-value-is-not-a-valid-distri","errorCode":null,"errorMessage":"pypi package name \"${value}\" is not a valid distribution name","messagePattern":"pypi package name \"(.+?)\" is not a valid distribution name","errorType":"validation","errorClass":"ArgumentError","httpStatus":null,"severity":"error","filePath":"clis/pypi/utils.js","lineNumber":16,"sourceCode":"// Shared helpers for the pypi adapters that hit the PyPI public JSON API\n// (pypi.org/pypi/<pkg>/json) and pypistats.org for download stats.\nimport { ArgumentError, CommandExecutionError, EmptyResultError } from '@jackwener/opencli/errors';\n\nexport const PYPI_BASE = 'https://pypi.org';\nexport const PYPISTATS_BASE = 'https://pypistats.org';\nconst UA = 'opencli-pypi-adapter (+https://github.com/jackwener/opencli)';\n\n// PEP 508 / PEP 426 normalized name: letters, digits, \"._-\", with leading-letter rule relaxed by PyPI.\nconst PKG_NAME = /^[A-Za-z0-9]([A-Za-z0-9._-]*[A-Za-z0-9])?$/;\n\nexport function requirePackageName(value) {\n    const s = String(value ?? '').trim();\n    if (!s) throw new ArgumentError('pypi package name is required (e.g. \"requests\", \"pandas\")');\n    if (!PKG_NAME.test(s)) {\n        throw new ArgumentError(\n            `pypi package name \"${value}\" is not a valid distribution name`,\n            'PyPI accepts ASCII letters / digits / \"._-\" with no leading or trailing separator.',\n        );\n    }\n    return s;\n}\n\nexport async function pypiFetch(url, label) {\n    let resp;\n    try {\n        resp = await fetch(url, { headers: { 'user-agent': UA, accept: 'application/json' } });\n    }\n    catch (err) {\n        throw new CommandExecutionError(\n            `${label} request failed: ${err?.message ?? err}`,\n            'Check that pypi.org / pypistats.org are reachable from this network.',\n        );\n    }","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/jackwener/OpenCLI/blob/49907e53dc3ade5c223ff0c4c2c2785687cec4e6/clis/pypi/utils.js#L1-L34","documentation":"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.","triggerScenarios":"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').","commonSituations":"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'.","solutions":["Use the bare canonical distribution name, e.g. `pypi package requests`","Strip extras/version specifiers from requirement strings before passing ('requests[security]>=2' → 'requests')","Normalize to PEP 503 form (lowercase, collapse runs of -_. to a single '-') if the source name is irregular"],"exampleFix":"// before\nawait pypiPackage('requests[security]>=2.0');\n// after\nawait pypiPackage('requests');","handlingStrategy":"validation","validationCode":"const PKG_NAME = /^[A-Za-z0-9]([A-Za-z0-9._-]*[A-Za-z0-9])?$/;\nif (!PKG_NAME.test(raw)) {\n  throw new Error(`\"${raw}\" is not a valid PyPI distribution name`);\n}","typeGuard":"function isValidPyPIName(v) {\n  return typeof v === 'string' && /^[A-Za-z0-9]([A-Za-z0-9._-]*[A-Za-z0-9])?$/.test(v);\n}","tryCatchPattern":"try {\n  await pypiPackage(raw);\n} catch (e) {\n  if (/not a valid distribution name/i.test(e.message)) {\n    console.error('Use the bare canonical name, e.g. requests (no extras/specifiers)');\n  } else throw e;\n}","preventionTips":["Strip extras and version specifiers from requirement strings before lookup","Normalize names per PEP 503 when sourcing from requirements files","Never paste URLs or pip command lines as the name argument"],"tags":["pypi","validation","invalid-name"],"backgroundTag":"schema-validation-failed","analyzedSha":"49907e53dc3ade5c223ff0c4c2c2785687cec4e6","analyzedAt":"2026-08-29T08:14:47.543Z","schemaVersion":2},"datasetVersion":"2026-08-29T12:17:43.993Z"}