pytest-dev/pytest · error · UsageError
: config option ' ' expects a list of strings, but item at…
Error message
{self.inipath}: config option '{name}' expects a list of strings, but item at index {i} is {item_type}: {item!r} What it means
Raised by pytest's TOML config parser when a 'paths'-type ini option is a list but contains a non-string element. TOML mode validates each list item is a string before resolving it to a pathlib.Path. The error names the offending index and the item's actual type.
Solutions
- Ensure every element in the paths array is a quoted string: change testpaths = ["tests", 42] to testpaths = ["tests", "42"]
- Remove non-path elements from the array if they were included by mistake
- Use `python -c` with tomllib to dump the parsed value and confirm all items are str
Example fix
// pyproject.toml — before [tool.pytest.ini_options] testpaths = ["tests", 42] // after [tool.pytest.ini_options] testpaths = ["tests", "42"]
Defensive patterns
Strategy: validation
Validate before calling
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 i, item in enumerate(val):
if not isinstance(item, str):
print(f"{key}[{i}]: expected str, got {type(item).__name__}: {item!r}") Type guard
def is_string_list(value: object) -> bool:
return isinstance(value, list) and all(isinstance(item, str) for item in value) Prevention
- Quote every element in a paths/args/linelist array in TOML
- Avoid mixing typed values (ints, bools) into string arrays
- Validate the parsed TOML structure before committing config changes
When it happens
Trigger: An ini option of type 'paths' is set to a TOML array containing integers, booleans, floats, nested tables, or inline arrays. Example: testpaths = ["tests", 42] — index 1 is an int. The per-item `isinstance(item, str)` check at the enumerate loop fails.
Common situations: Mixing path strings with numeric flags or inline tables in a paths array. Copying a config that worked in ini mode where list parsing was string-based. Accidental TOML auto-typing (e.g., an unquoted value parsed as a number).
Related errors
- : config option ' ' expects a list for type 'paths', got
- : 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/f5016b8dd772f962.
Report an issue: GitHub.
Appendix: source
Thrown at src/_pytest/config/__init__.py:1968
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.
if not isinstance(value, list):
raise TypeError(
f"{self.inipath}: config option '{name}' expects a list for type '{type}', "
f"got {value_type}: {value!r}"
)
for i, item in enumerate(value):
if not isinstance(item, str):View on GitHub (pinned to 0d6fbdeffa)