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
- Ensure the passed object subclasses poetry.plugins.plugin.Plugin or poetry.plugins.application_plugin.ApplicationPlugin.
- Check the import path — the base class must be imported from poetry.plugins, not a stale local copy.
- If using a mock in tests, subclass Plugin and override methods rather than passing a bare Mock.
- 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
- Always subclass Plugin or ApplicationPlugin when writing plugins.
- Import base classes from the canonical poetry.plugins path, not local copies.
- In tests, subclass the real base rather than mocking it.
- Run a smoke import of each plugin in CI to catch type mistakes early.
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
- : unknown direct dependency type
- Failed to install required Poetry plugins
- The command " " already exists.
- Unsupported file type
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)