pytest-dev/pytest · error · UsageError

invalid truth value

Error message

invalid truth value {val!r}

What it means

Raised by pytest's internal _strtobool() helper (copied from distutils.util.strtobool) when a string does not match any recognized truthy or falsy value. Accepted true values: 'y','yes','t','true','on','1'; accepted false values: 'n','no','f','false','off','0'. The comparison is case-insensitive (val is lowercased first).

Solutions

  1. Normalize the input before calling: strip whitespace and validate against the accepted set
  2. Map custom truthy/falsy strings to 'true'/'false' before passing to _strtobool
  3. Handle empty or None inputs separately before calling _strtobool

Example fix

# before
val = _strtobool(user_input)

# after
user_input = user_input.strip().lower()
if user_input not in ('y','yes','t','true','on','1','n','no','f','false','off','0'):
    raise ValueError(f"Cannot interpret {user_input!r} as boolean")
val = _strtobool(user_input)
Defensive patterns

Strategy: validation

Validate before calling

_TRUE = {'y', 'yes', 't', 'true', 'on', '1'}
_FALSE = {'n', 'no', 'f', 'false', 'off', '0'}
def safe_strtobool(val: str) -> bool:
    val = val.strip().lower()
    if val in _TRUE:
        return True
    if val in _FALSE:
        return False
    raise ValueError(f"invalid truth value {val!r}; expected one of {_TRUE | _FALSE}")

Type guard

def is_valid_truth_string(val: str) -> bool:
    return val.strip().lower() in {'y','yes','t','true','on','1','n','no','f','false','off','0'}

Try / catch

try:
    result = _strtobool(user_input)
except ValueError:
    result = False  # or prompt user for valid input

Prevention

When it happens

Trigger: Calling _strtobool() with a string outside the accepted set — e.g., 'maybe', '2', 'yep', '', or a string with surrounding whitespace that isn't stripped (since only .lower() is applied, not .strip()). pytest itself uses this for parsing boolean-like CLI values.

Common situations: Passing user-supplied or environment-variable strings that don't match the strict vocabulary. Whitespace or newlines in the input (not stripped). Localized values like 'si' or 'ja'. Empty string from an unset env var.

Related errors


AI-assisted analysis of pytest-dev/pytest@0d6fbdeffa (2026-08-11). Data as JSON: /api/errors/57637125a5a0acd8. Report an issue: GitHub.

Appendix: source

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

    return tw


def _strtobool(val: str) -> bool:
    """Convert a string representation of truth to True or False.

    True values are 'y', 'yes', 't', 'true', 'on', and '1'; false values
    are 'n', 'no', 'f', 'false', 'off', and '0'.  Raises ValueError if
    'val' is anything else.

    .. note:: Copied from distutils.util.
    """
    val = val.lower()
    if val in ("y", "yes", "t", "true", "on", "1"):
        return True
    elif val in ("n", "no", "f", "false", "off", "0"):
        return False
    else:
        raise ValueError(f"invalid truth value {val!r}")


@lru_cache(maxsize=50)
def parse_warning_filter(
    arg: str, *, escape: bool
) -> tuple[warnings._ActionKind, str, type[Warning], str, int]:
    """Parse a warnings filter string.

    This is copied from warnings._setoption with the following changes:

    * Does not apply the filter.
    * Escaping is optional.
    * Raises UsageError so we get nice error messages on failure.
    """
    __tracebackhide__ = True
    error_template = dedent(
        f"""\
        while parsing the following warning configuration:

View on GitHub (pinned to 0d6fbdeffa)