nodejs/node · error · InvalidName
name is invalid: {name!r}
Error message
name is invalid: {name!r} What it means
packaging.utils.InvalidName raised by canonicalize_name(name, validate=True) when name fails the core-metadata Name regex ^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$ (case-insensitive). Validation is opt-in; the default validate=False path canonicalizes anything without checking.
Source
Thrown at tools/gyp/pylib/packaging/utils.py:45
class InvalidSdistFilename(ValueError):
"""
An invalid sdist filename was found, users should refer to the packaging user guide.
"""
# Core metadata spec for `Name`
_validate_regex = re.compile(
r"^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$", re.IGNORECASE
)
_canonicalize_regex = re.compile(r"[-_.]+")
_normalized_regex = re.compile(r"^([a-z0-9]|[a-z0-9]([a-z0-9-](?!--))*[a-z0-9])$")
# PEP 427: The build number must start with a digit.
_build_tag_regex = re.compile(r"(\d+)(.*)")
def canonicalize_name(name: str, *, validate: bool = False) -> NormalizedName:
if validate and not _validate_regex.match(name):
raise InvalidName(f"name is invalid: {name!r}")
# This is taken from PEP 503.
value = _canonicalize_regex.sub("-", name).lower()
return cast(NormalizedName, value)
def is_normalized_name(name: str) -> bool:
return _normalized_regex.match(name) is not None
def canonicalize_version(
version: Union[Version, str], *, strip_trailing_zero: bool = True
) -> str:
"""
This is very similar to Version.__str__, but has one subtle difference
with the way it handles the release segment.
"""
if isinstance(version, str):
try:View on GitHub (pinned to 1b2de5e052)
Solutions
- Strip whitespace and confirm the name matches the regex before calling canonicalize_name(validate=True).
- Catch InvalidName and surface a user-friendly validation message at the input boundary.
- Use is_normalized_name() for a softer check, or canonicalize_name(validate=False) when you only want normalization.
Example fix
# before
name = canonicalize_name(raw, validate=True)
# after
try:
name = canonicalize_name(raw, validate=True)
except InvalidName:
raise ValueError(f'Please enter a valid project name: {raw!r}') Defensive patterns
Strategy: validation
Validate before calling
import re
_name_re = re.compile(r'^([A-Z0-9]|[A-Z0-9][A-Z0-9._-]*[A-Z0-9])$', re.IGNORECASE)
def is_valid_name(name: str) -> bool:
return bool(_name_re.match(name)) Type guard
from packaging.utils import canonicalize_name, InvalidName
def valid_name_or_none(name: str):
try:
return canonicalize_name(name, validate=True)
except InvalidName:
return None Try / catch
try:
norm = canonicalize_name(raw, validate=True)
except InvalidName as e:
raise ValueError(f'Invalid project name: {e}') from e Prevention
- Validate names at form/CLI input boundaries.
- Restrict accepted characters to letters, digits, ., _, -.
- Use validate=False when only normalization is needed.
When it happens
Trigger: Calling canonicalize_name(name, validate=True) with a name that is empty, starts/ends with a non-alphanumeric character, contains characters outside [A-Z0-9._-], or is a single underscore/dot/dash.
Common situations: Validating user-typed project names from a form or CLI, or sanitizing package names read from untrusted metadata before publishing.
Related errors
- Invalid project name: {filename}
- invalid metadata
- unparsed
- invalid or unparsed metadata
- Invalid specifier: '{spec}'
AI-assisted analysis of nodejs/node@1b2de5e052 (2026-08-13).
Data as JSON: /api/errors/38ddd2455e6eae50.
Report an issue: GitHub.