python-poetry/poetry · error · RuntimeError

Unable to read the lock file ({e}).

Error message

Unable to read the lock file ({e}).

What it means

Raised by Locker._get_lock_data() when tomllib.load() throws TOMLDecodeError while parsing the lockfile. It wraps the underlying parser error (with its message) in a RuntimeError so callers see a single failure type. The lockfile is structurally invalid TOML, not merely semantically wrong.

Source

Thrown at src/poetry/packages/locker.py:351

        if relevant_content:
            relevant_content["tool"] = {"poetry": relevant_poetry_content}
        else:
            # For backwards compatibility, we have to put the relevant content
            # of the [tool.poetry] section at top level!
            relevant_content = relevant_poetry_content

        return sha256(json.dumps(relevant_content, sort_keys=True).encode()).hexdigest()

    def _get_lock_data(self) -> dict[str, Any]:
        if not self.lock.exists():
            raise RuntimeError("No lockfile found. Unable to read locked packages")

        with self.lock.open("rb") as f:
            try:
                lock_data = tomllib.load(f)
            except tomllib.TOMLDecodeError as e:
                raise RuntimeError(f"Unable to read the lock file ({e}).")

        # if the lockfile doesn't contain a metadata section at all,
        # it probably needs to be rebuilt completely
        if "metadata" not in lock_data:
            raise RuntimeError(
                "The lock file does not have a metadata entry.\n"
                "Regenerate the lock file with the `poetry lock` command."
            )

        metadata = lock_data["metadata"]
        if "lock-version" not in metadata:
            raise RuntimeError(
                "The lock file is not compatible with the current version of Poetry.\n"
                "Regenerate the lock file with the `poetry lock` command."
            )
        lock_version = Version.parse(metadata["lock-version"])
        current_version = Version.parse(self._VERSION)
        accepted_versions = parse_constraint(self._READ_VERSION_RANGE)

View on GitHub (pinned to 92b74dcfe3)

Solutions

  1. Open poetry.lock and fix the TOML syntax error indicated by the embedded parse error message.
  2. If you cannot locate the error, regenerate from scratch with `poetry lock` (delete or back up the old poetry.lock first).
  3. Check `git diff poetry.lock` for unintended edits or conflict markers (<<<<<<<, =======, >>>>>>>).
  4. Ensure no editor/tool rewrote the file with CRLF or encoding changes.

Example fix

// before: merge conflict left in poetry.lock
[[package]]
name = "requests"
<<<<<<< HEAD
version = "2.31.0"
=======
version = "2.32.0"
>>>>>>> main

// after: resolve and run
$ poetry lock --no-update
Defensive patterns

Strategy: try-catch

Validate before calling

import tomllib
from pathlib import Path

def lockfile_is_valid(path: Path) -> bool:
    try:
        with path.open("rb") as f:
            tomllib.load(f)
        return True
    except (tomllib.TOMLDecodeError, OSError):
        return False

Try / catch

from poetry.packages import Locker

try:
    locker_data = locker._get_lock_data()
except RuntimeError as e:
    if "Unable to read the lock file" in str(e):
        # regenerate or report
        ...

Prevention

When it happens

Trigger: poetry.lock exists but contains malformed TOML — unbalanced quotes, duplicate keys, bad escaping, a botched manual edit, or a merge conflict left in place. Any command reading locked packages (install, show, update --lock) hits _get_lock_data().

Common situations: An unresolved git merge conflict inside poetry.lock; a hand edit that introduced a syntax error; a truncated file from a killed process or disk-full write; line-ending corruption on cross-platform checkouts.

Related errors


AI-assisted analysis of python-poetry/poetry@92b74dcfe3 (2026-08-04). Data as JSON: /data/errors/e1188768b1997655.json. Report an issue: GitHub.