pypa/pip · error · ValueError

invalid truth value {val!r}

Error message

invalid truth value {val!r}

What it means

Raised as ValueError by strtobool (misc.py:298) when the input string does not match any recognised truthy or falsy value. strtobool accepts 'y/yes/t/true/on/1' (returns 1) and 'n/no/f/false/off/0' (returns 0); any other input triggers this error. The function lowercases the input first, so case is not an issue, but any other content (empty string, typos, integer representations beyond 0/1) is rejected.

Source

Thrown at src/pip/_internal/utils/misc.py:298

    """Ask for a password interactively."""
    _check_no_input(message)
    return getpass.getpass(message)


def strtobool(val: str) -> int:
    """Convert a string representation of truth to true (1) or false (0).

    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.
    """
    val = val.lower()
    if val in ("y", "yes", "t", "true", "on", "1"):
        return 1
    elif val in ("n", "no", "f", "false", "off", "0"):
        return 0
    else:
        raise ValueError(f"invalid truth value {val!r}")


def format_size(bytes: float) -> str:
    if bytes > 1000 * 1000:
        return f"{bytes / 1000.0 / 1000:.1f} MB"
    elif bytes > 10 * 1000:
        return f"{int(bytes / 1000)} kB"
    elif bytes > 1000:
        return f"{bytes / 1000.0:.1f} kB"
    else:
        return f"{int(bytes)} bytes"


def tabulate(rows: Iterable[Iterable[Any]]) -> tuple[list[str], list[int]]:
    """Return a list of formatted rows and a list of column sizes.

    For example::

View on GitHub (pinned to f399c37189)

Solutions

  1. Set the environment variable or argument to a recognised value: one of yes/no/true/false/on/off/1/0 (case-insensitive).
  2. Validate the value before passing it to pip: ensure it matches the accepted set.
  3. If the value comes from user input in your own tool, normalise it to 'true' or 'false' before setting the pip env var.
  4. Unset the variable entirely if pip's default behaviour is acceptable.

Example fix

// before
export PIP_DISABLE_PIP_VERSION_CHECK=yeah

// after
export PIP_DISABLE_PIP_VERSION_CHECK=yes
Defensive patterns

Strategy: validation

Validate before calling

def normalize_bool_env(value: str) -> str:
    """Normalize arbitrary input to a strtobool-compatible value."""
    valid_true = {'y', 'yes', 't', 'true', 'on', '1'}
    valid_false = {'n', 'no', 'f', 'false', 'off', '0'}
    low = value.strip().lower()
    if low in valid_true:
        return '1'
    if low in valid_false:
        return '0'
    raise ValueError(f'{value!r} is not a valid boolean; use yes/no/true/false/on/off/1/0')

Type guard

def is_valid_strtobool(value: str) -> bool:
    """True if pip's strtobool will accept the value without error."""
    return value.strip().lower() in {
        'y', 'yes', 't', 'true', 'on', '1',
        'n', 'no', 'f', 'false', 'off', '0',
    }

Try / catch

try:
    from pip._internal.utils.misc import strtobool
    result = strtobool(user_input)
except ValueError:
    result = None  # or prompt for valid input

Prevention

When it happens

Trigger: strtobool is called with an unrecognised string, typically originating from an environment variable or CLI argument that pip passes through. For example PIP_* boolean flags parsed via strtobool where the user set an invalid value.

Common situations: Setting a boolean pip option via environment variable with an invalid value (PIP_VERIFY_CERTS=yes_no, PIP_QUIET=2). Passing --no-color when the underlying config expects strtobool-parseable input. Third-party tools or wrappers feeding unvalidated strings into pip config.

Related errors


AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08). Data as JSON: /api/errors/1c3a8f585b7a37fa. Report an issue: GitHub.