pypa/pip · error · PylockValidationError
Unexpected type (expected )
Error message
Unexpected type {type(item).__name__} (expected {expected_item_type.__name__}) What it means
Raised by _get_sequence in pylock.py:139-145 when iterating a TOML array: each element is checked against the expected item type (e.g. Mapping for dependencies, str for extras/dependency-groups). A wrong-typed element raises PylockValidationError with context 'key[i]'.
Solutions
- Make every element of the array the spec-required type (tables where Mapping is expected, strings where str is expected).
Example fix
# before
[[packages]]
dependencies = [{ name = "x" }, "y"]
# after
[[packages]]
dependencies = [{ name = "x" }, { name = "y" }] Defensive patterns
Strategy: validation
Validate before calling
from collections.abc import Mapping, Sequence
def array_items_typed(value, item_type: type) -> bool:
return isinstance(value, Sequence) and all(isinstance(i, item_type) for i in value)
Try / catch
from packaging.pylock import Pylock, PylockValidationError
try:
Pylock.from_dict(d)
except PylockValidationError as e:
# e.context is 'key[i]'
...
Prevention
- Keep pylock arrays homogeneous (all tables or all strings as the spec requires).
- Validate item types at the TOML-loading boundary.
When it happens
Trigger: In pylock TOML: dependencies = [{name = "x"}, "y"] (a string element among table elements), dependency-groups = ["dev", 42] (int element where str expected), attestation-identities = [{kind="..."}, "bad"].
Common situations: A mixed-type array; a stray scalar accidentally placed inside an array of tables; copy-paste leaving a placeholder string in a list.
Related errors
- Unexpected type (expected )
- Unexpected type (expected Sequence)
- Hash values must be strings
- Invalid pylock file
- At least one hash must be provided
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/66d3a2973583dc81.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_vendor/packaging/pylock.py:141
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."""
if (value := _get(d, Sequence, key)) is None: # type: ignore[type-abstract]
return None
if isinstance(value, (str, bytes)):
# special case: str and bytes are Sequences, but we want to reject it
raise PylockValidationError(
f"Unexpected type {type(value).__name__} (expected Sequence)",
context=key,
)
for i, item in enumerate(value):
if not isinstance(item, expected_item_type):
raise PylockValidationError(
f"Unexpected type {type(item).__name__} "
f"(expected {expected_item_type.__name__})",
context=f"{key}[{i}]",
)
return value
def _get_as(
d: Mapping[str, Any],
expected_type: type[_T],
target_type: Callable[[_T], _T2],
key: str,
) -> _T2 | None:
"""Get a value from the dictionary, verify it's the expected type,
and convert to the target type.
This assumes the target_type constructor accepts the value.
"""View on GitHub (pinned to f399c37189)