pypa/pip · error · ImportError

Entry point %r not found

Error message

Entry point %r not found

What it means

Raised as ImportError in Distribution.load_entry_point() at line 3180 when get_entry_info(group, name) returns None — meaning no entry point with that name exists in that group for this distribution. The message includes the (group, name) tuple for diagnosis.

Solutions

  1. Inspect available entry points with `dist.get_entry_map(group)` to see valid names.
  2. Correct the group or name to match what the package actually declares.
  3. Upgrade or downgrade the package to a version that has the desired entry point.
  4. Guard with try/except ImportError before calling load_entry_point.

Example fix

// before
dist.load_entry_point('console_scripts', 'old_name')
# ImportError: Entry point ('console_scripts', 'old_name') not found

// after
available = dist.get_entry_map('console_scripts')
name = next(iter(available), None)
if name:
    dist.load_entry_point('console_scripts', name)
Defensive patterns

Strategy: validation

Validate before calling

def entry_point_exists(dist, group, name) -> bool:
    ep_map = dist.get_entry_map(group)
    return name in ep_map

Type guard

def has_entry_point(dist, group: str, name: str) -> bool:
    return dist.get_entry_info(group, name) is not None

Try / catch

try:
    func = dist.load_entry_point('console_scripts', 'mycli')
except ImportError:
    func = None  # entry point not found; skip or fallback

Prevention

When it happens

Trigger: Calling `dist.load_entry_point('console_scripts', 'mycli')` on a distribution that has no 'mycli' entry point under 'console_scripts'. get_entry_info returns None when the name is absent from the parsed entry point map.

Common situations: Looking up a console_scripts or plugin entry point that was renamed or removed; querying the wrong distribution; version mismatch where the entry point was added in a later release; typo in the entry point name.

Related errors


AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08). Data as JSON: /api/errors/62602be763cf7bb5. Report an issue: GitHub.

Appendix: source

Thrown at src/pip/_vendor/pkg_resources/__init__.py:3180

    ):
        return cls.from_location(
            _normalize_cached(filename), os.path.basename(filename), metadata, **kw
        )

    def as_requirement(self):
        """Return a ``Requirement`` that matches this distribution exactly"""
        if isinstance(self.parsed_version, _packaging_version.Version):
            spec = "%s==%s" % (self.project_name, self.parsed_version)
        else:
            spec = "%s===%s" % (self.project_name, self.parsed_version)

        return Requirement.parse(spec)

    def load_entry_point(self, group: str, name: str) -> _ResolvedEntryPoint:
        """Return the `name` entry point of `group` or raise ImportError"""
        ep = self.get_entry_info(group, name)
        if ep is None:
            raise ImportError("Entry point %r not found" % ((group, name),))
        return ep.load()

    @overload
    def get_entry_map(self, group: None = None) -> dict[str, dict[str, EntryPoint]]: ...
    @overload
    def get_entry_map(self, group: str) -> dict[str, EntryPoint]: ...
    def get_entry_map(self, group: str | None = None):
        """Return the entry point map for `group`, or the full entry map"""
        if not hasattr(self, "_ep_map"):
            self._ep_map = EntryPoint.parse_map(
                self._get_metadata('entry_points.txt'), self
            )
        if group is not None:
            return self._ep_map.get(group, {})
        return self._ep_map

    def get_entry_info(self, group: str, name: str):
        """Return the EntryPoint object for `group`+`name`, or ``None``"""

View on GitHub (pinned to f399c37189)