{"record":{"id":"d057f8b0f4c86c73","repo":"pypa/pip","slug":"for-req-req-description-e-args-0","errorCode":null,"errorMessage":"For req: {req_description}. {e.args[0]}","messagePattern":"For req: (.+?)\\. (.+?)","errorType":"exception","errorClass":"InstallationError","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/operations/install/wheel.py","lineNumber":744,"sourceCode":"    )\n\n    # Record details of all files installed\n    record_path = os.path.join(dest_info_dir, \"RECORD\")\n\n    with _generate_file(record_path, **csv_io_kwargs(\"w\")) as record_file:\n        # Explicitly cast to typing.IO[str] as a workaround for the mypy error:\n        # \"writer\" has incompatible type \"BinaryIO\"; expected \"_Writer\"\n        writer = csv.writer(cast(\"IO[str]\", record_file))\n        writer.writerows(_normalized_outrows(rows))\n\n\n@contextlib.contextmanager\ndef req_error_context(req_description: str) -> Generator[None, None, None]:\n    try:\n        yield\n    except InstallationError as e:\n        message = f\"For req: {req_description}. {e.args[0]}\"\n        raise InstallationError(message) from e\n\n\ndef install_wheel(\n    name: str,\n    wheel_path: str,\n    scheme: Scheme,\n    req_description: str,\n    pycompile: bool = True,\n    warn_script_location: bool = True,\n    direct_url: DirectUrl | None = None,\n    requested: bool = False,\n    script_executable: str | None = None,\n) -> None:\n    with ZipFile(wheel_path, allowZip64=True) as z:\n        with req_error_context(req_description):\n            _install_wheel(\n                name=name,\n                wheel_zip=z,","sourceCodeStart":726,"sourceCodeEnd":762,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_internal/operations/install/wheel.py#L726-L762","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before: opaque failure during bulk install\npip install -r requirements.txt\n# after: isolate the failing req and surface the real cause\npip install --no-cache-dir -v <the-single-failing-package>","handlingStrategy":"try-catch","validationCode":"# No pre-API validation possible (it wraps arbitrary install failures).\n# Validate the wheel file is a sound zip before handing to pip.\nimport zipfile, sys\nfor whl in sys.argv[1:]:\n    if not zipfile.is_zipfile(whl):\n        print(f\"{whl} is not a valid zip/wheel\"); sys.exit(1)\n    bad = zipfile.ZipFile(whl).testzip()\n    if bad is not None:\n        print(f\"{whl} has corrupt member: {bad}\"); sys.exit(1)\nprint(\"wheels ok\")","typeGuard":"import zipfile, os\nfrom typing import TypeGuard\n\ndef is_installable_wheel(path: str) -> TypeGuard[str]:\n    return (os.path.isfile(path)\n            and path.endswith('.whl')\n            and zipfile.is_zipfile(path)\n            and zipfile.ZipFile(path).testzip() is None)","tryCatchPattern":"from subprocess import run, CalledProcessError\ntry:\n    run([\"pip\", \"install\", whl], check=True)\nexcept CalledProcessError as e:\n    # 'For req: ...' is pip's own message; surface it to the caller.\n    raise RuntimeError(f\"wheel install failed for {whl}: {e}\") from e","preventionTips":["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."],"tags":["wheel-install","installation","error-context","pip"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}