{"id":"bf738e81189fe25c","repo":"pypa/pip","slug":"bad-metadata-in-dist-invalid-metadata-entry-na","errorCode":null,"errorMessage":"Bad metadata in {dist} (invalid metadata entry 'name')","messagePattern":"Bad metadata in (.+?) \\(invalid metadata entry 'name'\\)","errorType":"exception","errorClass":"BadMetadata","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/metadata/importlib/_compat.py","lineNumber":86,"sourceCode":"    if suffix == \".egg-info\":\n        name = stem.split(\"-\", 1)[0]\n        return name, None\n\n    return None, None\n\n\ndef get_dist_canonical_name(dist: importlib.metadata.Distribution) -> NormalizedName:\n    \"\"\"Get the distribution's normalized name.\n\n    The ``name`` attribute is only available in Python 3.10 or later. We are\n    targeting exactly that, but Mypy does not know this.\n    \"\"\"\n    if name := parse_name_and_version_from_info_directory(dist)[0]:\n        return canonicalize_name(name)\n\n    name = cast(Any, dist).name\n    if not isinstance(name, str):\n        raise BadMetadata(dist, reason=\"invalid metadata entry 'name'\")\n    return canonicalize_name(name)\n","sourceCodeStart":68,"sourceCodeEnd":88,"githubUrl":"https://github.com/pypa/pip/blob/d7d0d0a39494e28ec1c407bd0680e4a4d1067791/src/pip/_internal/metadata/importlib/_compat.py#L68-L88","documentation":"BadMetadata (a ValueError subclass) raised by get_dist_canonical_name() when a distribution's 'name' field cannot be derived from its .dist-info directory name and the runtime .name attribute is not a string. It signals corrupt/non-conformant package metadata rather than a user config problem.","triggerScenarios":"Reached in the importlib.metadata backend when parse_name_and_version_from_info_directory returns no name (info dir not named 'name-version.dist-info' or not a .dist-info at all) and dist.name is None/non-str (e.g. None because the METADATA file lacks a Name header).","commonSituations":"A hand-built wheel whose .dist-info directory is misnamed (no version separator) and whose METADATA omits 'Name'; a corrupted site-packages after a partial install; a third-party tool generating non-compliant metadata.","solutions":["Reinstall the offending package from a known-good source (PyPI) to regenerate correct metadata.","Inspect the package's .dist-info directory: confirm it is named '<name>-<version>.dist-info' and that METADATA contains a 'Name' field.","Report the bad metadata to the package maintainer if it ships that way.","Remove the broken .dist-info/egg-info directory and reinstall."],"exampleFix":"; before - mypkg.dist-info/METADATA missing Name header\nMetadata-Version: 2.1\nVersion: 1.0\n\n; after\nMetadata-Version: 2.1\nName: mypkg\nVersion: 1.0","handlingStrategy":"validation","validationCode":"import importlib.metadata, pathlib\nfor d in importlib.metadata.distributions():\n    info = d._path  # PurePosixPath to info dir\n    name = info.name if info else None\n    if name and not name.endswith('.dist-info'):\n        continue\n    stem = name.rsplit('.dist-info',1)[0] if name else ''\n    if '-' not in stem and (getattr(d,'name',None) is None or not isinstance(d.name,str)):\n        print('suspicious metadata (no name):', info)","typeGuard":"def has_valid_name(dist) -> bool:\n    import importlib.metadata\n    name = getattr(dist, 'name', None)\n    return isinstance(name, str) and bool(name.strip())","tryCatchPattern":"from pip._internal.metadata.importlib._compat import BadMetadata\ntry:\n    get_dist_canonical_name(dist)\nexcept BadMetadata as e:\n    # reinstall the offending dist from a clean source\n    ...","preventionTips":["Install packages from reputable sources to get conformant metadata.","Build wheels with current backends that emit a Name header.","Verify .dist-info directory naming follows name-version convention.","Avoid hand-editing .dist-info directories."],"tags":["metadata","wheel","dist-info","corruption"],"analyzedSha":"d7d0d0a39494e28ec1c407bd0680e4a4d1067791","analyzedAt":"2026-08-04T20:55:04.259Z","schemaVersion":2}