python-poetry/poetry · error · ValueError

The Poetry plugin must be an instance of Plugin or…

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.

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: /api/errors/cc55455db7932c26. Report an issue: GitHub.

Appendix: 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)