pypa/pip · error · PylockValidationError
Hash values must be strings
Error message
Hash values must be strings
What it means
Raised as PylockValidationError by _validate_hashes in packaging.pylock when the hashes table is non-empty but at least one value is not a string. pylock requires every hash value to be a hex digest string; an int, list, or inline table value is rejected.
Source
Thrown at src/pip/_vendor/packaging/pylock.py:265
return path.rsplit("/", 1)[-1]
elif "\\" in path:
return path.rsplit("\\", 1)[-1]
else:
return path
def _url_name(url: str | None) -> str | None:
if not url:
return None
url_path = urlparse(url).path
return url_path.rsplit("/", 1)[-1]
def _validate_hashes(hashes: Mapping[str, Any]) -> Mapping[str, Any]:
if not hashes:
raise PylockValidationError("At least one hash must be provided")
if not all(isinstance(hash_val, str) for hash_val in hashes.values()):
raise PylockValidationError("Hash values must be strings")
return hashes
class PylockValidationError(Exception):
"""Raised when when input data is not spec-compliant."""
context: str | None = None
message: str
def __init__(
self,
cause: str | Exception,
*,
context: str | None = None,
) -> None:
if isinstance(cause, PylockValidationError):
if cause.context:
self.context = (View on GitHub (pinned to d7d0d0a394)
Solutions
- Ensure each hash value is a hex string, e.g. hashes = { sha256 = \"abcdef...\" }.
- Regenerate the lockfile with a resolver that writes hex digests.
- If generating programmatically, call hashlib.sha256(data).hexdigest().
- Validate the hashes mapping types before calling from_dict.
Example fix
# before
hashes = { sha256 = 123 }
# after
hashes = { sha256 = \"e3b0c44298fc1c149afbf4c8996fb924...\" } Defensive patterns
Strategy: type-guard
Validate before calling
def hashes_are_strings(h: dict) -> bool:
return all(isinstance(v, str) for v in h.values()) Type guard
from typing import Mapping
def is_string_valued_hashes(h: Mapping) -> bool:
return all(isinstance(v, str) for v in h.values()) Try / catch
try:
PylockFile.from_dict(data)
except PylockValidationError as e:
if 'Hash values must be strings' in str(e):
coerce_hash_values_to_hex_strings(e.context) Prevention
- Write hex digests via hashlib.<alg>.hexdigest().
- Validate hash value types before loading.
- Use a resolver that emits hex strings.
- Do not store hash lengths or nested objects.
When it happens
Trigger: hashes = { sha256 = 12345 } (int), hashes = { sha256 = [\"a\", \"b\"] } (list), or hashes = { sha256 = { digest = \"...\" } } (table). The error fires after the 'at least one hash' check has passed.
Common situations: Tooling that emits hash byte-length instead of the digest; a TOML converter that quoted only keys; copy-pasting a hash object instead of its hex attribute.
Related errors
- Unexpected type {type(value).__name__} (expected {expected_t
- Unexpected type {type(value).__name__} (expected Sequence)
- Unexpected type {type(item).__name__} (expected {expected_it
- At least one hash must be provided
- Name {name!r} is not normalized
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/88f9088495d98640.json.
Report an issue: GitHub.