python-poetry/poetry · error · ValueError

The Poetry plugin must be an instance of Plugin or Applicati

Error message

The Poetry plugin must be an instance of Plugin or ApplicationPlugin

What it means

Raised by PluginManager._add_plugin() when an object passed in is not an instance of Plugin or ApplicationPlugin. _add_plugin is the single chokepoint that registers activated plugins; the isinstance guard keeps the plugin list type-safe. This is an internal/programmatic API — end users rarely call it directly.

Source

Thrown at src/poetry/plugins/plugin_manager.py:90

    def ensure_project_plugins(cls, poetry: Poetry, io: IO) -> None:
        ProjectPluginCache(poetry, io).ensure_plugins()

    def load_plugins(self) -> None:
        plugin_entrypoints = self.get_plugin_entry_points()

        for ep in plugin_entrypoints:
            self._load_plugin_entry_point(ep)

    def get_plugin_entry_points(self) -> list[metadata.EntryPoint]:
        return list(metadata.entry_points(group=self._group))

    def activate(self, *args: Any, **kwargs: Any) -> None:
        for plugin in self._plugins:
            plugin.activate(*args, **kwargs)

    def _add_plugin(self, plugin: Plugin) -> None:
        if not isinstance(plugin, (Plugin, ApplicationPlugin)):
            raise ValueError(
                "The Poetry plugin must be an instance of Plugin or ApplicationPlugin"
            )

        self._plugins.append(plugin)

    def _load_plugin_entry_point(self, ep: metadata.EntryPoint) -> None:
        logger.debug("Loading the %s plugin", ep.name)

        plugin = ep.load()

        if not issubclass(plugin, (Plugin, ApplicationPlugin)):
            raise ValueError(
                "The Poetry plugin must be an instance of Plugin or ApplicationPlugin"
            )

        self._add_plugin(plugin())

View on GitHub (pinned to 92b74dcfe3)

Solutions

  1. Ensure the passed object subclasses poetry.plugins.plugin.Plugin or poetry.plugins.application_plugin.ApplicationPlugin.
  2. Check the import path — the base class must be imported from poetry.plugins, not a stale local copy.
  3. If using a mock in tests, subclass Plugin and override methods rather than passing a bare Mock.
  4. Reproduce the call in a REPL and inspect type(obj).__mro__ to see why the isinstance check fails.

Example fix

// before
from poetry.plugins.plugin_manager import PluginManager
pm._add_plugin(MyRandomClass())

// after
from poetry.plugins.plugin import Plugin
class MyPlugin(Plugin):
    def activate(self, application, io):
        ...
pm._add_plugin(MyPlugin())
Defensive patterns

Strategy: type-guard

Type guard

from poetry.plugins.plugin import Plugin
from poetry.plugins.application_plugin import ApplicationPlugin

def is_valid_plugin(obj: object) -> bool:
    return isinstance(obj, (Plugin, ApplicationPlugin))

Try / catch

from poetry.plugins.plugin_manager import PluginManager

try:
    pm._add_plugin(candidate)
except ValueError:
    # candidate is not a Plugin/ApplicationPlugin; skip or wrap it
    ...

Prevention

When it happens

Trigger: Code calls PluginManager._add_plugin(some_obj) (or a subclass overrides it) with an object that is neither a Plugin nor an ApplicationPlugin — e.g. passing a bare class, an unrelated object, or an instance whose base classes were not imported correctly.

Common situations: A third-party entry point that registers a non-plugin object; a test harness that injects a mock without subclassing Plugin; an import error that silently loaded a stub class; a plugin author subclassing the wrong base (e.g. a generic object).

Related errors


AI-assisted analysis of python-poetry/poetry@92b74dcfe3 (2026-08-04). Data as JSON: /data/errors/cc55455db7932c26.json. Report an issue: GitHub.