python-poetry/poetry · error · PoetryRuntimeError
<error>Failed to clone {url} at '{refspec.key}', verify ref
Error message
<error>Failed to clone {url} at '{refspec.key}', verify ref exists on remote.</> What it means
In the dulwich-based _clone, after fetching remote refs, refspec.resolve(remote_refs, repo=local) is called. A KeyError from resolve means the requested branch/tag/revision is not present among the advertised remote refs, so PoetryRuntimeError is raised telling you to verify the ref exists on the remote.
Source
Thrown at src/poetry/vcs/git/backend.py:345
ref spec.
"""
local: Repo
if not target.exists():
local = Repo.init(str(target), mkdir=True)
porcelain.remote_add(local, "origin", url)
else:
local = Repo(str(target))
remote_refs = cls._fetch_remote_refs(url=url, local=local)
logger.debug(
"Cloning <c2>%s</> at '<c2>%s</>' to <c1>%s</>", url, refspec.key, target
)
try:
refspec.resolve(remote_refs=remote_refs, repo=local)
except KeyError: # branch / ref does not exist
raise PoetryRuntimeError.create(
reason=f"<error>Failed to clone {url} at '{refspec.key}', verify ref exists on remote.</>",
info=[
ERROR_MESSAGE_NOTE,
ERROR_MESSAGE_PROBLEMS_SECTION_START_NETWORK_ISSUES,
ERROR_MESSAGE_BAD_REVISION.format(revision=refspec.key),
],
)
try:
# ensure local HEAD matches remote
ref = remote_refs.refs[Ref(b"HEAD")]
if ref is not None:
local.refs[Ref(b"HEAD")] = ref
except ValueError:
raise PoetryRuntimeError.create(
reason=f"<error>Failed to clone {url} at '{refspec.key}', verify ref exists on remote.</>",
info=[
ERROR_MESSAGE_NOTE,View on GitHub (pinned to 92b74dcfe3)
Solutions
- Run `git ls-remote <url>` to confirm the ref is actually advertised.
- Fix the rev/branch/tag in pyproject.toml to an existing remote ref.
- Push the missing ref to the remote if it should be there.
- Use an explicit full commit sha to avoid ambiguity.
Example fix
# before
lib = { git = "https://github.com/acme/lib.git", tag = "v1.2" } # tag does not exist
# after - verify with: git ls-remote --tags https://github.com/acme/lib.git
lib = { git = "https://github.com/acme/lib.git", tag = "v1.2.3" } Defensive patterns
Strategy: validation
Validate before calling
import subprocess
def remote_has_ref(url: str, ref: str) -> bool:
out = subprocess.run(
['git', 'ls-remote', url], capture_output=True, text=True,
).stdout
return any(ref in line for line in out.splitlines()) Try / catch
from poetry.exceptions import PoetryRuntimeError
try:
... # operation triggering a dulwich clone
except PoetryRuntimeError as e:
if 'verify ref exists on remote' in str(e):
raise Prevention
- Use `git ls-remote <url>` to confirm the ref is advertised.
- Pin to concrete commit shas to avoid ref resolution failures.
- Update pyproject when upstream refs are renamed or deleted.
When it happens
Trigger: A git dependency whose rev/branch/tag is not advertised by the remote (typo, deleted ref, ref only in a fork), cloned via dulwich.
Common situations: Branch renamed or deleted upstream; rev is a short sha ambiguous or absent; pointing at a tag that doesn't exist; ref lives only on a different remote/fork.
Related errors
- <error>Failed to clone <info>{url}</>, check your git config
- <error>Failed to checkout {url} at '{revision}'.</>
- <error>Failed to clone {url} at '{refspec.key}', unable to a
- Unsupported VCS dependency {vcs}
- Invalid Git parameter: {parameter}
AI-assisted analysis of python-poetry/poetry@92b74dcfe3 (2026-08-04).
Data as JSON: /data/errors/fa8a0ab03ce436a3.json.
Report an issue: GitHub.