pypa/pip · error · InstallationError
Invalid pylock file
Error message
Invalid pylock file {pylock_path_or_url!r}: {exc} What it means
Raised as InstallationError by select_from_pylock_path_or_url (pylock.py:288) when the pylock file content was read successfully but fails to parse or validate against the pylock schema. The code at line 286 calls tomllib.loads to parse TOML and Pylock.from_dict to validate; any exception from either (malformed TOML, missing required fields, wrong types) is caught at line 287 and re-raised with context. The original exception is chained.
Solutions
- Validate the TOML syntax independently: `python -c "import tomllib; tomllib.load(open('pylock.toml','rb'))"`.
- Check the error message (from the chained exception) for the specific field or syntax problem and fix it.
- Regenerate the lock file with a compatible tool (`pip lock` or pip-tools with pylock support).
- Ensure the lock_version in the file matches what your pip version supports (currently 1.0).
Example fix
// before (invalid TOML) lock-version = 1.0 [[packages name = "pkg" // after lock-version = "1.0" [[packages]] name = "pkg"
Defensive patterns
Strategy: validation
Validate before calling
import tomllib
from pathlib import Path
def validate_pylock_toml(path: str) -> list[str]:
"""Pre-validate a pylock.toml's TOML syntax; return list of errors."""
errors = []
try:
data = tomllib.loads(Path(path).read_text(encoding='utf-8'))
except tomllib.TOMLDecodeError as e:
errors.append(f'TOML syntax error: {e}')
return errors
for key in ('lock-version', 'packages'):
if key not in data:
errors.append(f'Missing required field: {key}')
return errors Type guard
def is_valid_pylock_toml(path: str) -> bool:
"""True if the file parses as valid TOML with required pylock keys."""
try:
data = tomllib.loads(Path(path).read_text(encoding='utf-8'))
return 'lock-version' in data and 'packages' in data
except Exception:
return False Try / catch
from pip._internal.exceptions import InstallationError
try:
# pip install -r pylock.toml
pass
except InstallationError as e:
if 'Invalid pylock file' in str(e):
# parse error: validate TOML independently and fix schema
pass Prevention
- Validate TOML syntax with a standalone parser before installing from lock files.
- Use a schema validator for pylock files in your CI pipeline.
- Regenerate lock files with supported tools rather than hand-editing them.
When it happens
Trigger: Loading a pylock.toml that has TOML syntax errors (unquoted keys, bad escaping), is not a valid pylock file (missing required top-level fields like lock_version, packages), or has package entries that fail Pylock.from_dict schema validation. The except at line 287 catches it.
Common situations: A hand-edited lock file with TOML syntax errors. A lock file generated by an incompatible or outdated tool. A partially-written or truncated lock file. Schema version mismatch (lock_version not supported).
Related errors
- Unexpected type (expected )
- Unexpected type (expected )
- Unexpected type (expected Sequence)
- At least one hash must be provided
- Cannot determine sdist filename
AI-assisted analysis of pypa/pip@f399c37189 (2026-08-08).
Data as JSON: /api/errors/b315c2007164666f.
Report an issue: GitHub.
Appendix: source
Thrown at src/pip/_internal/utils/pylock.py:288
) -> Iterator[
tuple[
Package,
PackageVcs | PackageDirectory | PackageArchive | PackageWheel | PackageSdist,
]
]:
try:
pylock_content = _get_pylock_path_or_url_content(pylock_path_or_url, session)
except DiagnosticPipError:
raise
except Exception as exc:
raise InstallationError(
f"Error reading pylock file {pylock_path_or_url!r}: {exc}"
) from exc
try:
lock = Pylock.from_dict(tomllib.loads(pylock_content))
except Exception as exc:
raise InstallationError(
f"Invalid pylock file {pylock_path_or_url!r}: {exc}"
) from exc
try:
# TODO: for completeness, pylock.select should support preferring sdist
# over wheels to support --no-binary
yield from lock.select()
except Exception as exc:
raise InstallationError(
f"Cannot select requirements from pylock file {pylock_path_or_url!r}: {exc}"
) from exc
View on GitHub (pinned to f399c37189)