python-poetry/poetry · error · CleoLogicError

The command "{command_name}" already exists.

Error message

The command "{command_name}" already exists.

What it means

Raises cleo's CleoLogicError when CommandLoader.register_factory() is called with a command_name that already exists in the internal _factories dict. The CommandLoader (a FactoryCommandLoader subclass) prevents two factories from being registered under the same command name, which would create ambiguity in command dispatch. This is a programmer/plugin-author error, not an end-user mistake.

Source

Thrown at src/poetry/console/command_loader.py:20

from typing import TYPE_CHECKING

from cleo.exceptions import CleoLogicError
from cleo.loaders.factory_command_loader import FactoryCommandLoader


if TYPE_CHECKING:
    from collections.abc import Callable

    from cleo.commands.command import Command


class CommandLoader(FactoryCommandLoader):
    def register_factory(
        self, command_name: str, factory: Callable[[], Command]
    ) -> None:
        if command_name in self._factories:
            raise CleoLogicError(f'The command "{command_name}" already exists.')

        self._factories[command_name] = factory

View on GitHub (pinned to 92b74dcfe3)

Solutions

  1. Check whether command_name is already in command_loader._factories before calling register_factory.
  2. Rename your plugin's command to use a unique prefix or namespace to avoid collisions.
  3. Ensure the plugin is not registered more than once (check plugin entry points and Poetry's plugin loading).

Example fix

# before
command_loader.register_factory("build", my_factory)
# after
if "build" not in command_loader._factories:
    command_loader.register_factory("my-plugin-build", my_factory)
Defensive patterns

Strategy: validation

Validate before calling

def safe_register(command_loader, name, factory):
    if name in command_loader._factories:
        raise ValueError(f"Command '{name}' is already registered")
    # or silently skip / use an alternate name
    alt_name = f"my-plugin:{name}"
    command_loader.register_factory(alt_name, factory)

Type guard

def is_command_available(command_loader, name) -> bool:
    return name not in command_loader._factories

Try / catch

from cleo.exceptions import CleoLogicError

try:
    command_loader.register_factory("my-command", my_factory)
except CleoLogicError:
    # Command name already taken; choose a unique name
    command_loader.register_factory("my-plugin:my-command", my_factory)

Prevention

When it happens

Trigger: A Poetry plugin calls command_loader.register_factory('my-command', MyFactory) when 'my-command' was already registered by another plugin or by Poetry's own built-in command set. Also triggered by calling register_factory twice with the same name.

Common situations: Two plugins independently register commands with the same name, a plugin registers a command name that collides with a built-in Poetry command (e.g. 'add', 'install', 'build'), or a plugin is loaded multiple times due to misconfiguration.

Related errors


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