pypa/pip · error · ValueError
Including subprocess data sources from specific root_dir is
Error message
Including subprocess data sources from specific root_dir is disallowed to prevent false information
What it means
Raised by distro.LinuxDistribution.__init__ when the caller passes both root_dir (a custom filesystem root to read os-release / distro-release files from) and at least one subprocess-based data source flag (include_lsb, include_uname, or include_oslevel). The library forbids this combination because lsb_release, uname, and oslevel run as live subprocesses against the host system and cannot be scoped to an alternate root_dir, so mixing them would silently produce data from two different systems.
Source
Thrown at src/pip/_vendor/distro/distro.py:786
etc_dir_os_release_file = os.path.join(self.etc_dir, _OS_RELEASE_BASENAME)
usr_lib_os_release_file = os.path.join(
self.usr_lib_dir, _OS_RELEASE_BASENAME
)
# NOTE: The idea is to respect order **and** have it set
# at all times for API backwards compatibility.
if os.path.isfile(etc_dir_os_release_file) or not os.path.isfile(
usr_lib_os_release_file
):
self.os_release_file = etc_dir_os_release_file
else:
self.os_release_file = usr_lib_os_release_file
self.distro_release_file = distro_release_file or "" # updated later
is_root_dir_defined = root_dir is not None
if is_root_dir_defined and (include_lsb or include_uname or include_oslevel):
raise ValueError(
"Including subprocess data sources from specific root_dir is disallowed"
" to prevent false information"
)
self.include_lsb = (
include_lsb if include_lsb is not None else not is_root_dir_defined
)
self.include_uname = (
include_uname if include_uname is not None else not is_root_dir_defined
)
self.include_oslevel = (
include_oslevel if include_oslevel is not None else not is_root_dir_defined
)
def __repr__(self) -> str:
"""Return repr of all info"""
return (
"LinuxDistribution("
"os_release_file={self.os_release_file!r}, "View on GitHub (pinned to f399c37189)
Solutions
- Set include_lsb=False, include_uname=False, include_oslevel=False when passing root_dir, and rely only on the os-release / distro-release files inside that root.
- If you need uname/lsb_release data, call distro without root_dir so all sources come from the live system consistently.
- Run lsb_release/uname manually against the target environment and merge results yourself.
Example fix
# before info = LinuxDistribution(root_dir='/mnt/sysroot', include_lsb=True) # after info = LinuxDistribution(root_dir='/mnt/sysroot', include_lsb=False, include_uname=False)
Defensive patterns
Strategy: validation
Validate before calling
def make_linux_distribution(root_dir=None, include_lsb=None, include_uname=None, include_oslevel=None):
if root_dir is not None and (include_lsb or include_uname or include_oslevel):
raise ValueError('Cannot combine root_dir with subprocess data sources')
import distro
return distro.LinuxDistribution(
root_dir=root_dir,
include_lsb=include_lsb if root_dir is None else False,
include_uname=include_uname if root_dir is None else False,
include_oslevel=include_oslevel if root_dir is None else False,
) Try / catch
try:
info = LinuxDistribution(root_dir=path, include_lsb=True)
except ValueError as e:
if 'root_dir' in str(e):
info = LinuxDistribution(root_dir=path, include_lsb=False)
else:
raise Prevention
- When inspecting a chroot/image, always set all include_* flags to False.
- Document that root_dir and subprocess sources are mutually exclusive.
- Wrap LinuxDistribution construction in a helper that enforces the constraint.
When it happens
Trigger: Constructing LinuxDistribution(root_dir='/chroot/path', include_lsb=True) or any combination where root_dir is set and include_lsb/include_uname/include_oslevel is explicitly True.
Common situations: Inspecting a mounted disk image or chroot for its OS identity while also wanting uname/lsb_release data; copying example code that set include_lsb=True and then adding root_dir; library wrapper that unconditionally passes both.
Related errors
- Editor Subprocess exited with exit code {returncode}
- Got invalid value for load_only - should be one of {}
- [dependency-groups] data was invalid in {path}: {'; '.join(m
- invalid truth value {val!r}
- limit must be non-negative
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/2af74558891713f5.
Report an issue: GitHub.