pypa/pip · error · InstallationError
For req: .
Error message
For req: {req_description}. {e.args[0]} What it means
This is a generic error-context wrapper (the req_error_context context manager at wheel.py:738). It does not raise a new failure; it catches any InstallationError raised while installing a specific wheel and re-raises it with 'For req: <description>.' prepended, preserving the original cause via 'from e'. Its purpose is to attach the requirement identity to an otherwise opaque wheel-installation failure so the user knows which package broke.
Solutions
- Read the text AFTER 'For req: ...' in the message — that is the underlying InstallationError and the actual root cause to fix.
- Re-download the wheel (clear pip cache: pip cache purge) in case of a corrupt/partial download.
- Check filesystem permissions and free disk space in the target environment/site-packages.
- Retry with -v / --no-cache-dir to get the original traceback and pinpoint which install sub-step failed.
Example fix
# before: opaque failure during bulk install pip install -r requirements.txt # after: isolate the failing req and surface the real cause pip install --no-cache-dir -v <the-single-failing-package>
Defensive patterns
Strategy: try-catch
Validate before calling
# No pre-API validation possible (it wraps arbitrary install failures).
# Validate the wheel file is a sound zip before handing to pip.
import zipfile, sys
for whl in sys.argv[1:]:
if not zipfile.is_zipfile(whl):
print(f"{whl} is not a valid zip/wheel"); sys.exit(1)
bad = zipfile.ZipFile(whl).testzip()
if bad is not None:
print(f"{whl} has corrupt member: {bad}"); sys.exit(1)
print("wheels ok") Type guard
import zipfile, os
from typing import TypeGuard
def is_installable_wheel(path: str) -> TypeGuard[str]:
return (os.path.isfile(path)
and path.endswith('.whl')
and zipfile.is_zipfile(path)
and zipfile.ZipFile(path).testzip() is None) Try / catch
from subprocess import run, CalledProcessError
try:
run(["pip", "install", whl], check=True)
except CalledProcessError as e:
# 'For req: ...' is pip's own message; surface it to the caller.
raise RuntimeError(f"wheel install failed for {whl}: {e}") from e Prevention
- Pre-validate wheels with zipfile.testzip() before invoking pip install.
- Always re-raise pip subprocess failures with context about which requirement failed.
- Keep disk space and write permissions healthy in the install target.
When it happens
Trigger: Raised inside install_wheel/_install_wheel whenever the per-wheel install step (unzipping, copying files, compiling bytecode, writing RECORD) throws an InstallationError. The message you actually see is the ORIGINAL InstallationError text (e.args[0]) with the requirement description prefixed.
Common situations: Corrupt or malformed wheel files (missing RECORD, bad zip), permission errors writing into site-packages, .pyc compilation failures on read-only environments, or disk-full during file copy. Because it is a wrapper, the real problem is in the trailing portion of the message.
Related errors
- Directory is not installable. Neither 'setup.py' nor…
- Editable requirements are not allowed as constraints
- An error occurred while writing to the configuration file
- Can not perform a '--user' install. User site-packages are…
- Can't verify hashes for these file:// requirements because…
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/d057f8b0f4c86c73.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_internal/operations/install/wheel.py:744
)
# Record details of all files installed
record_path = os.path.join(dest_info_dir, "RECORD")
with _generate_file(record_path, **csv_io_kwargs("w")) as record_file:
# Explicitly cast to typing.IO[str] as a workaround for the mypy error:
# "writer" has incompatible type "BinaryIO"; expected "_Writer"
writer = csv.writer(cast("IO[str]", record_file))
writer.writerows(_normalized_outrows(rows))
@contextlib.contextmanager
def req_error_context(req_description: str) -> Generator[None, None, None]:
try:
yield
except InstallationError as e:
message = f"For req: {req_description}. {e.args[0]}"
raise InstallationError(message) from e
def install_wheel(
name: str,
wheel_path: str,
scheme: Scheme,
req_description: str,
pycompile: bool = True,
warn_script_location: bool = True,
direct_url: DirectUrl | None = None,
requested: bool = False,
script_executable: str | None = None,
) -> None:
with ZipFile(wheel_path, allowZip64=True) as z:
with req_error_context(req_description):
_install_wheel(
name=name,
wheel_zip=z,View on GitHub (pinned to f399c37189)