python-poetry/poetry · error · ValueError
pyproject.toml changed significantly since poetry.lock was l
Error message
pyproject.toml changed significantly since poetry.lock was last generated. Run `{self._lock_fix_command()}` to fix the lock file. What it means
Raised by Installer._do_install at src/poetry/installation/installer.py:267-271 when self._locker.is_fresh() returns False during a non-update install. Poetry detects that pyproject.toml's content hash no longer matches the one recorded in poetry.lock, meaning dependencies changed without re-locking. ValueError; the message includes the exact command to run.
Source
Thrown at src/poetry/installation/installer.py:268
):
solved_packages = solver.solve(
use_latest=self._whitelist
).get_solved_packages()
if not self.executor.enabled:
# If we are only in lock mode, no need to go any further
self._write_lock_file(solved_packages)
return 0
for package in solved_packages:
if not lockfile_repo.has_package(package):
lockfile_repo.add_package(package)
else:
self._io.write_line("<info>Installing dependencies from lock file</>")
if not self._locker.is_fresh():
raise ValueError(
"pyproject.toml changed significantly since poetry.lock was last"
f" generated. Run `{self._lock_fix_command()}` to fix the lock file."
)
if not (reresolve or self._locker.is_locked_groups_and_markers()):
if self._io.is_verbose():
self._io.write_line(
"<info>Cannot install without re-resolving"
" because the lock file is not at least version 2.1</>"
)
reresolve = True
locker_extras = {
canonicalize_name(extra)
for extra in self._locker.lock_data.get("extras", {})
}
for extra in self._extras:
if extra not in locker_extras:
raise ValueError(f"Extra [{extra}] is not specified.")View on GitHub (pinned to 92b74dcfe3)
Solutions
- Run the exact command printed in the message (usually `poetry lock --no-update`) to refresh poetry.lock while keeping versions.
- If the lock is badly out of date, run `poetry lock` to fully re-resolve.
- Commit the regenerated poetry.lock alongside the pyproject.toml change.
Example fix
# before $ poetry install ValueError: pyproject.toml changed significantly since poetry.lock ... Run `poetry lock --no-update` ... # after $ poetry lock --no-update $ poetry install
Defensive patterns
Strategy: validation
Validate before calling
from poetry.packages.locker import Locker
locker = Locker(local_lock, pyproject_data)
if not locker.is_fresh():
raise SystemExit(
'pyproject.toml out of sync with poetry.lock; run `poetry lock --no-update` first.'
) Try / catch
try:
installer.run()
except ValueError as e:
if 'pyproject.toml changed significantly' in str(e):
import subprocess
subprocess.run(['poetry', 'lock', '--no-update'], check=True)
installer.run()
raise Prevention
- Always commit poetry.lock together with pyproject.toml dependency changes.
- Use `poetry add`/`poetry remove` instead of editing dependencies by hand.
When it happens
Trigger: Editing [tool.poetry.dependencies] (or any section that affects the lock's content hash) and then running `poetry install` without `poetry lock` first. Reached in the else branch of _do_install (the install-from-lock path).
Common situations: Adding/removing a dependency in pyproject.toml via editor instead of `poetry add/remove`, merging a branch that changed dependencies, or a teammate's commit that updated pyproject.toml but not poetry.lock.
Related errors
- Extra [{extra}] is not specified.
- Missing [url] in source {name!r}.
- Bad script ({name}): script needs to specify a function with
- Setting {self.argument('key')} does not exist
- You can only pass one value.
AI-assisted analysis of python-poetry/poetry@92b74dcfe3 (2026-08-04).
Data as JSON: /data/errors/9a5f643f25a8e291.json.
Report an issue: GitHub.