{"record":{"id":"bb5e8787fab7ac84","repo":"pypa/pip","slug":"hashes-are-required-in-require-hashes-mode-but","errorCode":null,"errorMessage":"Hashes are required in --require-hashes mode, but they are missing from some requirements. Here is a list of those requirements along with the hashes their downloaded archives actually had. Add lines like these to your requirements files to prevent tampering. (If you did not enable --require-hashes manually, note that it turns on automatically when any package has a hash.)","messagePattern":"Hashes are required in --require-hashes mode, but they are missing from some requirements\\. Here is a list of those requirements along with the hashes their downloaded archives actually had\\. Add lines like these to your requirements files to prevent tampering\\. \\(If you did not enable --require-hashes manually, note that it turns on automatically when any package has a hash\\.\\)","errorType":"exception","errorClass":"HashMissing","httpStatus":null,"severity":"error","filePath":"src/pip/_internal/utils/hashes.py","lineNumber":150,"sourceCode":"        )\n\n\nclass MissingHashes(Hashes):\n    \"\"\"A workalike for Hashes used when we're missing a hash for a requirement\n\n    It computes the actual hash of the requirement and raises a HashMissing\n    exception showing it to the user.\n\n    \"\"\"\n\n    def __init__(self) -> None:\n        \"\"\"Don't offer the ``hashes`` kwarg.\"\"\"\n        # Pass our favorite hash in to generate a \"gotten hash\". With the\n        # empty list, it will never match, so an error will always raise.\n        super().__init__(hashes={FAVORITE_HASH: []})\n\n    def _raise(self, gots: dict[str, _Hash]) -> NoReturn:\n        raise HashMissing(gots[FAVORITE_HASH].hexdigest())\n","sourceCodeStart":132,"sourceCodeEnd":151,"githubUrl":"https://github.com/pypa/pip/blob/f399c3718970b1b0e2478dac5296eb62679a9b86/src/pip/_internal/utils/hashes.py#L132-L151","documentation":"Raised as HashMissing by MissingHashes._raise (hashes.py:150) when --require-hashes mode is active (either explicitly or auto-enabled because another package has a hash) and a requirement has no hash specified at all. MissingHashes is initialised with an empty allowed-list for sha256 so the check always fails, then _raise outputs the actual computed hash so the user can copy it into their requirements file. The message instructs the user to add the missing --hash lines.","triggerScenarios":"Running pip install with --require-hashes where at least one requirement lacks a --hash entry. Also triggers automatically when any single requirement in the file has a hash: pip turns on require-hashes globally (hashes.py:147), and MissingHashes is used for the requirement without one. _raise at line 150 fires after the download completes and the computed sha256 doesn't match the empty allowed list.","commonSituations":"Enabling --require-hashes but forgetting to add hashes for some requirements. Adding a hash to one package which auto-enables hash checking for all dependencies, catching the ones without hashes. New transitive dependencies introduced by a version bump that lack hashes.","solutions":["Copy the hash lines that pip prints in the error message and paste them into your requirements file for the affected package(s).","Run `pip install --require-hashes --dry-run -r requirements.txt` (or pip hash) to pre-compute hashes for all packages.","Regenerate the entire lock file with hashes using `pip freeze --all` or a tool like pip-tools (`pip-compile --generate-hashes`).","If you did not intend hash-locked mode, remove all --hash entries from your requirements file to disable auto-enabling."],"exampleFix":"// before\npackage-a==1.0 --hash=sha256:abc...\npackage-b==2.0\n\n// after\npackage-a==1.0 --hash=sha256:abc...\npackage-b==2.0 --hash=sha256:def...  (from error output)","handlingStrategy":"validation","validationCode":"import re\n\ndef find_requirements_without_hashes(path: str) -> list[str]:\n    \"\"\"Return package specs that lack a --hash in a requirements file.\"\"\"\n    missing = []\n    with open(path) as f:\n        for line in f:\n            line = line.strip()\n            if not line or line.startswith('#'):\n                continue\n            if '==' in line and '--hash=' not in line:\n                missing.append(line)\n    return missing\n\n# Run before pip install --require-hashes","typeGuard":null,"tryCatchPattern":"from pip._internal.exceptions import HashMissing\n\ntry:\n    # pip install --require-hashes operation\n    pass\nexcept HashMissing as e:\n    # e.hash_value contains the computed hash to add\n    print(f'Add this hash: sha256:{e.hash_value}')","preventionTips":["Use pip-compile --generate-hashes to produce fully-hashed lock files.","Audit lock files for any package spec lacking a --hash before enabling --require-hashes.","Remember: adding a hash to ANY package auto-enables require-hashes for all packages."],"tags":["hashes","require-hashes","missing-hash","requirements-file"],"backgroundTag":null,"analyzedSha":"f399c3718970b1b0e2478dac5296eb62679a9b86","analyzedAt":"2026-08-08T23:01:42.227Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}