abhigyanpatwari/GitNexus · critical · RuntimeError
clone object is hardlinked to host storage: {obj}
Error message
clone object is hardlinked to host storage: {obj} What it means
Thrown by make_worktree during its post-clone isolation audit. Even with --no-hardlinks, the harness walks every file under target/.git/objects and rejects any with a link count (st_nlink) greater than 1, because a hardlinked object means the arm shares physical storage with the host and a mutation in one affects the other.
Source
Thrown at eval/workflow_bench/runner_artifacts.py:324
run_checked(
[
"git",
"clone",
"--no-local",
"--no-hardlinks",
"--no-tags",
"--quiet",
str(repo),
str(target),
],
timeout=600,
)
alternates = target / ".git" / "objects" / "info" / "alternates"
if alternates.exists():
raise RuntimeError(f"clone unexpectedly has an external object alternate: {alternates}")
for obj in (target / ".git" / "objects").rglob("*"):
if obj.is_file() and obj.stat().st_nlink > 1:
raise RuntimeError(f"clone object is hardlinked to host storage: {obj}")
for candidate in (ref, f"origin/{ref}"):
proc = run_managed(
["git", "-C", str(target), "checkout", "--detach", "--quiet", candidate],
timeout=60,
)
if proc.ok:
return target
raise RuntimeError(f"ref {ref!r} not found in clone of {repo}")
except BaseException as primary:
if target.exists():
try:
shutil.rmtree(target)
except OSError as cleanup:
primary.add_note(f"clone cleanup also failed: {type(cleanup).__name__}: {cleanup}")
raise
def remove_clone(clone: Path) -> None:View on GitHub (pinned to d540b00184)
Solutions
- Ensure source repo and target live on different filesystems/devices so hardlinking is impossible, or rely on the --no-local transport the harness already requests.
- Do not copy or rsync the resulting clone with hard-link options.
- Use the harness's own make_worktree rather than a manual clone, since it already passes --no-local --no-hardlinks.
- Upgrade git; older versions had bugs where --no-hardlinks was not honored in all paths.
Example fix
// before — manual clone that may hardlink subprocess.run(['git','clone', str(repo), str(target)]) # same-volume -> hardlinks // after — use the harness helper which forces --no-local --no-hardlinks from eval.workflow_bench.runner_artifacts import make_worktree target = make_worktree(repo, ref, parent=tempfile.gettempdir())
Defensive patterns
Strategy: validation
Validate before calling
from pathlib import Path
def no_hardlinked_objects(target: Path) -> bool:
objects = target / '.git' / 'objects'
return all(f.stat().st_nlink == 1 for f in objects.rglob('*') if f.is_file()) Type guard
null
Try / catch
try:
make_worktree(repo, ref, parent)
except RuntimeError as e:
if 'hardlinked to host storage' in str(e):
# move source/target to different filesystems, or stop copying with -l
raise
raise Prevention
- Always use make_worktree (which passes --no-local --no-hardlinks) instead of a manual clone.
- Keep source repo and target on different filesystems so hardlinking is impossible.
- Never rsync/cp the clone with --link-dest or -l.
- After any manual clone, assert no_hardlinked_objects(target) before proceeding.
When it happens
Trigger: For some object file `obj` under target/.git/objects, `obj.stat().st_nlink > 1`. A file there is hardlinked to a file outside the clone (or to another clone's object).
Common situations: A filesystem or git version that ignores --no-hardlinks; copying the worktree with `cp -l`/rsync --link-dest; a host with link-based dedup; the source repo and target on the same volume such that git fell back to hardlinks despite the flag.
Related errors
- clone unexpectedly has an external object alternate: {altern
- ref {ref!r} not found in clone of {repo}
- generated artifact is not a regular non-symlink file: {path}
- generated artifact changed type while opening: {path}
- GitNexus MCP executable must stay outside {SANDBOX_WORKSPACE
AI-assisted analysis of abhigyanpatwari/GitNexus@d540b00184 (2026-08-12).
Data as JSON: /api/errors/4a684d769a4b51d4.
Report an issue: GitHub.