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

  1. 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.
  2. If you need uname/lsb_release data, call distro without root_dir so all sources come from the live system consistently.
  3. 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 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


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