pypa/pip · error · PylockValidationError
Unexpected type {type(value).__name__} (expected {expected_t
Error message
Unexpected type {type(value).__name__} (expected {expected_type.__name__}) What it means
Raised as PylockValidationError by _get in packaging.pylock when a TOML value for a key exists but is not the expected scalar type. pylock (PEP 771 lockfile) strictly type-checks every field; for example 'size' must be int, 'name' must be str. The context field records the offending key path.
Source
Thrown at src/pip/_vendor/packaging/pylock.py:103
if isinstance(value, Sequence) and key == "environments":
return [str(v) for v in value]
return value
def _toml_dict_factory(data: list[tuple[str, Any]]) -> dict[str, Any]:
return {
_toml_key(key): _toml_value(key, value)
for key, value in data
if value is not None
}
def _get(d: Mapping[str, Any], expected_type: type[_T], key: str) -> _T | None:
"""Get a value from the dictionary and verify it's the expected type."""
if (value := d.get(key)) is None:
return None
if not isinstance(value, expected_type):
raise PylockValidationError(
f"Unexpected type {type(value).__name__} "
f"(expected {expected_type.__name__})",
context=key,
)
return value
def _get_required(d: Mapping[str, Any], expected_type: type[_T], key: str) -> _T:
"""Get a required value from the dictionary and verify it's the expected type."""
if (value := _get(d, expected_type, key)) is None:
raise _PylockRequiredKeyError(key)
return value
def _get_sequence(
d: Mapping[str, Any], expected_item_type: type[_T], key: str
) -> Sequence[_T] | None:
"""Get a list value from the dictionary and verify it's the expected items type."""View on GitHub (pinned to d7d0d0a394)
Solutions
- Open the pylock.toml and correct the value to the expected type shown in the error.
- Regenerate the lockfile with a compliant resolver rather than editing by hand.
- Pre-validate the TOML against the pylock JSON schema before loading.
- Catch PylockValidationError and report the offending key (e.context) to the user.
Example fix
# before size = \"1024\" # after size = 1024
Defensive patterns
Strategy: type-guard
Validate before calling
def check_types(d, spec):
# spec: {key: expected_type}
for k, t in spec.items():
v = d.get(k)
if v is not None and not isinstance(v, t):
raise TypeError(f'{k}: expected {t.__name__}, got {type(v).__name__}') Type guard
def is_correct_type(value, expected_type) -> bool:
return value is None or isinstance(value, expected_type) Try / catch
from packaging.pylock import PylockValidationError
try:
PylockFile.from_dict(data)
except PylockValidationError as e:
log.error('pylock field %s: %s', e.context, e.message) Prevention
- Generate lockfiles with a compliant resolver.
- Validate TOML field types before loading.
- Catch PylockValidationError and report e.context.
- Avoid hand-editing scalar fields.
When it happens
Trigger: Loading a pylock.toml where size = \"12345\" (string instead of int), or upload-time = 12345 (int instead of ISO str), or name = 42. Calling PylockFile.from_dict on a hand-built dict with wrong types.
Common situations: Hand-edited lockfiles; tooling that emits numbers as strings; schema drift between pylock versions; YAML->TOML converters that lose typing.
Related errors
- Unexpected type {type(value).__name__} (expected Sequence)
- Unexpected type {type(item).__name__} (expected {expected_it
- Hash values must be strings
- Invalid pylock file {pylock_path_or_url!r}: {exc}
- Name {name!r} is not normalized
AI-assisted analysis of pypa/pip@d7d0d0a394 (2026-08-04).
Data as JSON: /data/errors/a9d0f828ef91be38.json.
Report an issue: GitHub.