pytest-dev/pytest · error · UsageError

{filepath}: {exc}

Error message

{filepath}: {exc}

What it means

Raised when pytest's config loader fails to parse a TOML configuration file (pytest.toml, .pytest.toml, or the [tool.pytest] section of pyproject.toml) due to malformed TOML syntax. The stdlib tomllib (or tomli on older Python) raises TOMLDecodeError, which pytest wraps as a UsageError prefixed with the file path.

Source

Thrown at src/_pytest/config/findpaths.py:106

        elif "pytest" in iniconfig.sections:
            # If a setup.cfg contains a "[pytest]" section, we raise a failure to indicate users that
            # plain "[pytest]" sections in setup.cfg files is no longer supported (#3086).
            fail(CFG_PYTEST_SECTION.format(filename="setup.cfg"), pytrace=False)

    # '.toml' files are considered if they contain a [tool.pytest] table (toml mode)
    # or [tool.pytest.ini_options] table (ini mode) for pyproject.toml,
    # or [pytest] table (toml mode) for pytest.toml/.pytest.toml.
    elif filepath.suffix == ".toml":
        if sys.version_info >= (3, 11):
            import tomllib
        else:
            import tomli as tomllib

        toml_text = filepath.read_text(encoding="utf-8")
        try:
            config = tomllib.loads(toml_text)
        except tomllib.TOMLDecodeError as exc:
            raise UsageError(f"{filepath}: {exc}") from exc

        # pytest.toml and .pytest.toml use [pytest] table directly.
        if filepath.name in ("pytest.toml", ".pytest.toml"):
            if "pytest" in config:
                # TOML mode - preserve native TOML types.
                return {
                    k: ConfigValue(v, origin="file", mode="toml")
                    for k, v in config["pytest"].items()
                }
            top_level_options = [
                key for key, value in config.items() if not isinstance(value, dict)
            ]
            if top_level_options:
                raise UsageError(
                    f"{filepath}: pytest configuration must be under a "
                    f"[pytest] table (found top-level options: "
                    f"{', '.join(top_level_options)})"
                )

View on GitHub (pinned to 98b357f69e)

Solutions

  1. Validate the TOML file: python -c 'import tomllib; tomllib.loads(open('pyproject.toml').read())'.
  2. Use a TOML linter or editor with TOML syntax checking.
  3. Fix the specific syntax error described in the wrapped TOMLDecodeError message (line/column shown).

Example fix

# before (unquoted value)
[tool.pytest.ini_options]
addopts = -v

# after
[tool.pytest.ini_options]
addopts = '-v'
Defensive patterns

Strategy: try-catch

Validate before calling

import sys, pathlib
try:
    import tomllib
except ImportError:
    import tomli as tomllib

def validate_toml(path: pathlib.Path) -> None:
    try:
        tomllib.loads(path.read_text(encoding='utf-8'))
    except tomllib.TOMLDecodeError as e:
        raise ValueError(f'{path}: {e}') from e

Try / catch

try:
    config = tomllib.loads(text)
except tomllib.TOMLDecodeError as exc:
    raise ValueError(f'{filepath}: {exc}') from exc

Prevention

When it happens

Trigger: A pyproject.toml or pytest.toml with syntax errors: unquoted strings, mismatched brackets, trailing characters, invalid escape sequences, or duplicate keys. tomllib.loads() raises TOMLDecodeError at line 104-106.

Common situations: Hand-editing pyproject.toml and introducing a syntax error; merging tool sections incorrectly; copying TOML from a source that used a different format; using TOML features unsupported by the bundled parser version.

Related errors


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