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
- Validate the TOML file: python -c 'import tomllib; tomllib.loads(open('pyproject.toml').read())'.
- Use a TOML linter or editor with TOML syntax checking.
- 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
- Run a TOML parse check on pyproject.toml in pre-commit / CI.
- Use an editor with TOML syntax highlighting and validation.
- Quote string values and avoid mixing array/inline-table syntax carelessly.
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
- {filepath}: pytest configuration must be under a [pytest] ta
- {filepath}: Cannot use both [tool.pytest] (native TOML types
- {self.inipath}: config option '{name}' expects one of {_ini_
- {self.inipath}: config option '{name}' expects a string, got
- {self.inipath}: config option '{name}' expects a list for ty
AI-assisted analysis of pytest-dev/pytest@98b357f69e (2026-08-04).
Data as JSON: /data/errors/741a02fdb389b798.json.
Report an issue: GitHub.