pytest-dev/pytest · error · UsageError
: config option ' ' expects a list for type 'paths', got
Error message
{self.inipath}: config option '{name}' expects a list for type 'paths', got {value_type}: {value!r} What it means
Raised by pytest's TOML config parser (_getini_toml) when an ini option declared with type 'paths' is set to a non-list value in pyproject.toml or tox.ini. Unlike legacy ini parsing, TOML mode performs strict type validation with no coercion — the value must already be a native TOML array. The error includes the config file path, option name, actual type, and the offending value.
Solutions
- Wrap the value in square brackets in pyproject.toml: change `testpaths = "tests"` to `testpaths = ["tests"]`
- Verify the TOML file parses to a list by checking with a TOML parser or `python -c "import tomllib; print(tomllib.loads(open('pyproject.toml','rb').read())['tool']['pytest']['ini_options']['testpaths'])"`
- If you intentionally want a single path, still use a single-element list: testpaths = ["tests"]
Example fix
// pyproject.toml — before [tool.pytest.ini_options] testpaths = "tests" // after [tool.pytest.ini_options] testpaths = ["tests"]
Defensive patterns
Strategy: validation
Validate before calling
# Before writing pyproject.toml, validate paths options parse as lists
import tomllib
with open('pyproject.toml', 'rb') as f:
data = tomllib.load(f)
opts = data.get('tool', {}).get('pytest', {}).get('ini_options', {})
for key, val in opts.items():
if isinstance(val, list):
for item in val:
if not isinstance(item, str):
print(f"{key}: item {item!r} is not a string")
elif key in ('testpaths', 'python_files', 'python_classes', 'python_functions'):
print(f"{key}: expected a list, got {type(val).__name__}") Type guard
def is_path_list(value: object) -> bool:
return isinstance(value, list) and all(isinstance(item, str) for item in value) Prevention
- Always use TOML inline arrays for paths-type options: key = ["value"]
- Run `python -c "import tomllib; ..."` to validate config after editing pyproject.toml
- Migrate pytest.ini values to TOML arrays when moving to pyproject.toml
When it happens
Trigger: A plugin or pytest itself registers an ini option with addini(type='paths'). The user provides a scalar (e.g., a string or integer) instead of an inline array in the [tool.pytest.ini_options] section of pyproject.toml. Example: testpaths = "tests" instead of testpaths = ["tests"]. The check `isinstance(value, list)` fails and TypeError is raised.
Common situations: Migrating from pytest.ini (where bare strings are accepted for path options) to pyproject.toml without converting the value to a TOML array. Copying TOML snippets from outdated blog posts. Confusing TOML syntax (a quoted string is not an array).
Related errors
- : config option ' ' expects a list of strings, but item at…
- : config option ' ' expects a bool, got
- : config option ' ' expects a float, got
- : config option ' ' expects a list for type ' ', got
- : config option ' ' expects a string, got
AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11).
Data as JSON: /api/errors/c4b2483c8c494bfc.
Report an issue: GitHub.
Appendix: source
Thrown at src/_pytest/config/__init__.py:1961
def _getini_toml(
self,
name: str,
canonical_name: str,
type: str,
value: object,
default: Any,
):
"""Handle TOML config values with strict type validation and no coercion.
In TOML mode, values already have native types from TOML parsing.
We validate types match expectations exactly, including list items.
"""
value_type = builtins.type(value).__name__
if type == "paths":
# Expect a list of strings.
if not isinstance(value, list):
raise TypeError(
f"{self.inipath}: config option '{name}' expects a list for type 'paths', "
f"got {value_type}: {value!r}"
)
for i, item in enumerate(value):
if not isinstance(item, str):
item_type = builtins.type(item).__name__
raise TypeError(
f"{self.inipath}: config option '{name}' expects a list of strings, "
f"but item at index {i} is {item_type}: {item!r}"
)
dp = (
self.inipath.parent
if self.inipath is not None
else self.invocation_params.dir
)
return [dp / x for x in value]
elif type in {"args", "linelist"}:
# Expect a list of strings.View on GitHub (pinned to 0d6fbdeffa)