{"id":"e1188768b1997655","repo":"python-poetry/poetry","slug":"unable-to-read-the-lock-file-e","errorCode":null,"errorMessage":"Unable to read the lock file ({e}).","messagePattern":"Unable to read the lock file \\((.+?)\\)\\.","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"src/poetry/packages/locker.py","lineNumber":351,"sourceCode":"\n        if relevant_content:\n            relevant_content[\"tool\"] = {\"poetry\": relevant_poetry_content}\n        else:\n            # For backwards compatibility, we have to put the relevant content\n            # of the [tool.poetry] section at top level!\n            relevant_content = relevant_poetry_content\n\n        return sha256(json.dumps(relevant_content, sort_keys=True).encode()).hexdigest()\n\n    def _get_lock_data(self) -> dict[str, Any]:\n        if not self.lock.exists():\n            raise RuntimeError(\"No lockfile found. Unable to read locked packages\")\n\n        with self.lock.open(\"rb\") as f:\n            try:\n                lock_data = tomllib.load(f)\n            except tomllib.TOMLDecodeError as e:\n                raise RuntimeError(f\"Unable to read the lock file ({e}).\")\n\n        # if the lockfile doesn't contain a metadata section at all,\n        # it probably needs to be rebuilt completely\n        if \"metadata\" not in lock_data:\n            raise RuntimeError(\n                \"The lock file does not have a metadata entry.\\n\"\n                \"Regenerate the lock file with the `poetry lock` command.\"\n            )\n\n        metadata = lock_data[\"metadata\"]\n        if \"lock-version\" not in metadata:\n            raise RuntimeError(\n                \"The lock file is not compatible with the current version of Poetry.\\n\"\n                \"Regenerate the lock file with the `poetry lock` command.\"\n            )\n        lock_version = Version.parse(metadata[\"lock-version\"])\n        current_version = Version.parse(self._VERSION)\n        accepted_versions = parse_constraint(self._READ_VERSION_RANGE)","sourceCodeStart":333,"sourceCodeEnd":369,"githubUrl":"https://github.com/python-poetry/poetry/blob/92b74dcfe348d0e01e14d40d6c1fa47a4ee04a54/src/poetry/packages/locker.py#L333-L369","documentation":"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.","triggerScenarios":"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().","commonSituations":"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.","solutions":["Open poetry.lock and fix the TOML syntax error indicated by the embedded parse error message.","If you cannot locate the error, regenerate from scratch with `poetry lock` (delete or back up the old poetry.lock first).","Check `git diff poetry.lock` for unintended edits or conflict markers (<<<<<<<, =======, >>>>>>>).","Ensure no editor/tool rewrote the file with CRLF or encoding changes."],"exampleFix":"// before: merge conflict left in poetry.lock\n[[package]]\nname = \"requests\"\n<<<<<<< HEAD\nversion = \"2.31.0\"\n=======\nversion = \"2.32.0\"\n>>>>>>> main\n\n// after: resolve and run\n$ poetry lock --no-update","handlingStrategy":"try-catch","validationCode":"import tomllib\nfrom pathlib import Path\n\ndef lockfile_is_valid(path: Path) -> bool:\n    try:\n        with path.open(\"rb\") as f:\n            tomllib.load(f)\n        return True\n    except (tomllib.TOMLDecodeError, OSError):\n        return False","typeGuard":null,"tryCatchPattern":"from poetry.packages import Locker\n\ntry:\n    locker_data = locker._get_lock_data()\nexcept RuntimeError as e:\n    if \"Unable to read the lock file\" in str(e):\n        # regenerate or report\n        ...","preventionTips":["Never hand-edit poetry.lock; always use poetry commands.","Resolve all merge conflicts in poetry.lock before committing.","Validate poetry.lock in a pre-commit hook with a TOML parser.","Avoid editors that auto-reformat TOML on save for the lockfile."],"tags":["lockfile","toml","parsing"],"analyzedSha":"92b74dcfe348d0e01e14d40d6c1fa47a4ee04a54","analyzedAt":"2026-08-04T20:33:34.072Z","schemaVersion":2}