pytest-dev/pytest · error · TypeError

`args` parameter expected to be a list of strings, got: {!r}

Error message

`args` parameter expected to be a list of strings, got: {!r} (type: {})

What it means

The _prepareconfig function requires the args parameter to be a list of strings (or a single os.PathLike). If args is any other type (tuple, string, dict, int, etc.), pytest raises TypeError. This is a guard for programmatic pytest.main() callers who pass the wrong collection type.

Source

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

    This function can be used by integration with other tools, like hooking
    into pytest to run tests into an IDE.
    """
    return get_config().pluginmanager


def _prepareconfig(
    args: list[str] | os.PathLike[str],
    plugins: Sequence[str | _PluggyPlugin] | None = None,
    *,
    prog: str | None = None,
) -> Config:
    if isinstance(args, os.PathLike):
        args = [os.fspath(args)]
    elif not isinstance(args, list):
        msg = (  # type:ignore[unreachable]
            "`args` parameter expected to be a list of strings, got: {!r} (type: {})"
        )
        raise TypeError(msg.format(args, type(args)))

    initial_config = get_config(args, plugins, prog=prog)
    pluginmanager = initial_config.pluginmanager
    try:
        if plugins:
            for plugin in plugins:
                if isinstance(plugin, str):
                    pluginmanager.consider_pluginarg(plugin)
                else:
                    pluginmanager.register(plugin)
        config: Config = pluginmanager.hook.pytest_cmdline_parse(
            pluginmanager=pluginmanager, args=args
        )
        return config
    except BaseException:
        initial_config._ensure_unconfigure()
        raise

View on GitHub (pinned to 98b357f69e)

Solutions

  1. Pass args as a list of strings: pytest.main(['-v', 'tests/']).
  2. If args is a tuple, convert it: pytest.main(list(args)).
  3. If args is a single PathLike, it is accepted directly; otherwise wrap any string in a list.

Example fix

# before
import pytest
pytest.main('-v -s tests/')  # string, not list

# after
import pytest
pytest.main(['-v', '-s', 'tests/'])
Defensive patterns

Strategy: type-guard

Validate before calling

import os
from collections.abc import Sequence

def coerce_pytest_args(args):
    if isinstance(args, os.PathLike):
        return [os.fspath(args)]
    if isinstance(args, list):
        return args
    if isinstance(args, str):
        # A single string is ambiguous; split on spaces if it looks like CLI flags
        return args.split()
    if isinstance(args, Sequence):
        return list(args)
    raise TypeError(f"args must be a list of strings, got {type(args).__name__}")

# usage: pytest.main(coerce_pytest_args(my_args))

Type guard

from collections.abc import Sequence
import os

def is_valid_pytest_args(args) -> bool:
    return isinstance(args, (list, os.PathLike)) or (isinstance(args, str) and False)  # str alone is NOT valid

Prevention

When it happens

Trigger: Calling pytest.main(args) or pytest.main(args, plugins) where args is a string (e.g., 'tests/'), a tuple, or another non-list type. The isinstance(args, list) check fails and TypeError is raised.

Common situations: Developers calling pytest.main() programmatically and passing a single string like '-v -s tests/' instead of ['-v', '-s', 'tests/']. Also migration from older pytest versions where looser typing was tolerated.

Related errors


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