pytest-dev/pytest · error · ValueError

option names {conflict} already added

Error message

option names {conflict} already added

What it means

Raised by OptionGroup.addoption() when one or more of the supplied option strings (e.g. '--flag') have already been registered by a previous addoption call in the same parser. pytest rejects duplicate option names to prevent ambiguous command-line parsing.

Source

Thrown at src/_pytest/config/argparsing.py:457

        """Add an option to this group.

        If a shortened version of a long option is specified, it will
        be suppressed in the help. ``addoption('--twowords', '--two-words')``
        results in help showing ``--two-words`` only, but ``--twowords`` gets
        accepted **and** the automatic destination is in ``args.twowords``.

        :param opts:
            Option names, can be short or long options.
            Note that lower-case short options (e.g. `-x`) are reserved.
        :param attrs:
            Same attributes as the argparse library's :meth:`add_argument()
            <argparse.ArgumentParser.add_argument>` function accepts.
        """
        conflict = set(opts).intersection(
            name for opt in self.options for name in opt.names()
        )
        if conflict:
            raise ValueError(f"option names {conflict} already added")

        if self.parser and "dest" not in attrs:
            dest = _get_argparse_dest(opts)
            for group in self.parser._groups:
                for option in group.options:
                    if option.dest == dest:
                        raise ValueError(
                            f"option dest {dest!r} already used by "
                            f"{option.names()!r} (this is the option that maps to "
                            f"dest {dest!r}); pass dest={dest!r} explicitly "
                            "to share the destination"
                        )
        self._addoption_inner(opts, attrs, allow_reserved=False)

    def _addoption(self, *opts: str, **attrs: Any) -> None:
        """Like addoption(), but also allows registering short lower case options (e.g. -x),
        which are reserved for pytest core."""
        self._addoption_inner(opts, attrs, allow_reserved=True)

View on GitHub (pinned to 98b357f69e)

Solutions

  1. Remove the duplicate addoption from your conftest or plugin.
  2. Guard registration with a check like `if not parser.getoption('--myflag', default=None)`.
  3. Rename your custom option to a plugin-namespaced form (e.g. '--myplugin-flag').
  4. Disable the conflicting plugin via -p no:pluginname.

Example fix

# before
def pytest_addoption(parser):
    parser.addoption('--foo', ...)
    parser.addoption('--foo', ...)  # duplicate

# after
def pytest_addoption(parser):
    parser.addoption('--foo', ...)
    parser.addoption('--plugin-foo', ...)
Defensive patterns

Strategy: validation

Validate before calling

def option_already_registered(existing: list, *opts: str) -> bool:
    names = {n for opt in existing for n in opt}
    return bool(set(opts) & names)

Try / catch

try:
    group.addoption('--myflag', ...)
except ValueError as e:
    if 'already added' in str(e):
        pass  # already registered by another plugin; skip

Prevention

When it happens

Trigger: Two addoption calls registering the same '--myflag', or a plugin re-registering an option that pytest core or another plugin already added. The set intersection at line 453-455 finds the conflict.

Common situations: Loading two plugins that both define the same option; a conftest.py adding an option that a plugin also adds; upgrading a plugin that newly defines an option your conftest already defines.

Related errors


AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04). Data as JSON: /data/errors/dc72fa8f91e88a1c.json. Report an issue: GitHub.