pytest-dev/pytest · error · ValueError

{self.inipath}: config option '{name}' expects one of {_ini_

Error message

{self.inipath}: config option '{name}' expects one of {_ini_type_repr(type)}, got {value!r}

What it means

Raised by Config._getini_value (config/__init__.py:1868-1872) for a Literal/choice ini option: the value IS a string but it is not present in the registered .choices tuple. This is the standard 'value not in allowed choices' rejection, surfaced as UsageError.

Source

Thrown at src/_pytest/config/__init__.py:1869

        self,
        mode: Literal["ini", "toml"],
        name: str,
        canonical_name: str,
        type: str | _IniLiteral,
        value: object,
        default: Any,
    ):
        """Convert a config value, read in the given mode, to the option's type."""
        if isinstance(type, _IniLiteral):
            # A Literal value is a plain string checked against the registered
            # choices, without coercion, in both ini and toml modes.
            if not isinstance(value, str):
                raise TypeError(
                    f"{self.inipath}: config option '{name}' expects a string, "
                    f"got {builtins.type(value).__name__}: {value!r}"
                )
            if value not in type.choices:
                raise ValueError(
                    f"{self.inipath}: config option '{name}' expects one of "
                    f"{_ini_type_repr(type)}, got {value!r}"
                )
            return value
        if mode == "ini":
            # In ini mode, values are always str | list[str].
            assert isinstance(value, (str, list))
            return self._getini_ini(name, canonical_name, type, value, default)
        elif mode == "toml":
            return self._getini_toml(name, canonical_name, type, value, default)
        else:
            assert_never(mode)

    def _getini_ini(
        self,
        name: str,
        canonical_name: str,
        type: str,

View on GitHub (pinned to 98b357f69e)

Solutions

  1. Consult the error's 'expects one of' list and pick one of the named choices.
  2. Fix casing/typos to match a registered choice exactly.
  3. If a custom plugin, extend addini choices to include the new value, or switch to a free-form type.

Example fix

# before (pyproject.toml)
[tool.pytest.ini_options]
log_level = "informational"

# after
log_level = "INFO"
Defensive patterns

Strategy: validation

Validate before calling

def validate_choice(value, choices):
    if value not in choices:
        raise ValueError(f'{value!r} not in {choices}')
    return value

Type guard

def is_allowed_choice(value, choices) -> bool:
    return isinstance(value, str) and value in choices

Try / catch

try:
    config.getini(name)
except Exception as e:
    # pick the closest valid choice from the message and update config

Prevention

When it happens

Trigger: Supplying a string for a choice option that is not in the allowed set registered via addini(choices=[...]). Common with log_level, log_auto_indent, or custom plugin choice options.

Common situations: Typo in a choice value (e.g. 'WARRNING' vs 'WARNING'); using a value valid in an older pytest version but removed/renamed; passing a lowercase value when choices are uppercase.

Related errors


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