python-poetry/poetry · error · PoetryRuntimeError

<error>Failed to clone {url} at '{refspec.key}', unable to a

Error message

<error>Failed to clone {url} at '{refspec.key}', unable to acquire file lock for {to_str(e.filename)}.</>

What it means

During dulwich _clone, when importing refs (refs/remotes/origin and refs/tags), a dulwich FileLocked exception means another process is holding (or left) a lock file inside the local clone/cache directory. PoetryRuntimeError reports the locked path and lock filename. This is a concurrency/stale-lock condition, not a bad ref.

Source

Thrown at src/poetry/vcs/git/backend.py:396

            try:
                local.refs.import_refs(
                    base=base,
                    other={
                        Ref(n[len(prefix) :]): v
                        for (n, v) in remote_refs.refs.items()
                        if n.startswith(prefix)
                        and not n.endswith(PEELED_TAG_SUFFIX)
                        and v is not None
                    },
                )
            except FileLocked as e:

                def to_str(path: bytes | str) -> str:
                    if isinstance(path, bytes):
                        path = path.decode()
                    return path.replace(os.sep * 2, os.sep)

                raise PoetryRuntimeError.create(
                    # <https://github.com/jelmer/dulwich/pull/2045> should clean up the
                    # ignore.
                    reason=(
                        f"<error>Failed to clone {url} at '{refspec.key}',"
                        f" unable to acquire file lock for {to_str(e.filename)}.</>"
                    ),
                    info=[
                        ERROR_MESSAGE_NOTE,
                        ERROR_MESSAGE_PROBLEMS_SECTION_START,
                        ERROR_MESSAGE_FILE_LOCK.format(
                            lock_file=to_str(e.lockfilename)
                        ),
                    ],
                )

        try:
            with local:
                local.get_worktree().reset_index()

View on GitHub (pinned to 92b74dcfe3)

Solutions

  1. Remove the stale lock file(s) named in the exception (e.filename / lockfilename) under the clone/cache directory.
  2. Avoid running concurrent Poetry operations against the same cache; give each job an isolated cache/venv.
  3. Clear Poetry's git/VCS cache to force a clean re-clone.
  4. Retry after ensuring no other process holds the lock.

Example fix

# before - parallel jobs share $POETRY_CACHE_DIR -> FileLocked
# after - give each job its own cache
export POETRY_CACHE_DIR=/tmp/poetry-cache-$CI_CONCURRENT_ID
poetry install
Defensive patterns

Strategy: fallback

Validate before calling

from pathlib import Path

def no_stale_locks(clone_dir: Path) -> bool:
    return not any(clone_dir.rglob('*.lock'))

Try / catch

from poetry.exceptions import PoetryRuntimeError
from pathlib import Path
import shutil

try:
    ...  # clone
except PoetryRuntimeError as e:
    if 'unable to acquire file lock' in str(e):
        cache = Path.home() / '.cache' / 'pypoetry' / 'vcs'
        shutil.rmtree(cache, ignore_errors=True)  # clear stale locks
        raise

Prevention

When it happens

Trigger: Two Poetry processes (e.g. parallel CI matrix jobs, an IDE plus a CLI) cloning the same repository into the same cached checkout simultaneously, or a previous clone that crashed and left a .lock file behind.

Common situations: Parallel builds sharing a Poetry/git cache directory; an interrupted `poetry install` leaving a stale dulwich lock; filesystem that doesn't reap locks cleanly.

Related errors


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