can1357/oh-my-pi · error · GitCommandError
GitCommandError: git worktree prune failed (nonzero exit)
Error message
GitCommandError: git worktree prune failed (nonzero exit)
What it means
When `git worktree add` fails, _worktree_add deletes the partially created repo_dir and attempts `git worktree prune` to clean the pool's stale worktree registrations. If the prune itself fails, its GitCommandError is chained from the original add error and raised — signaling the pool's worktree metadata is in a bad state that automatic cleanup could not fix.
Source
Thrown at python/robomp/src/sandbox.py:414
def _worktree_add(add_cmd: list[str], *, pool: Path, repo_dir: Path) -> None:
"""Run `git worktree add`, cleaning partial state on failure.
A worktree-add killed mid-operation (the 120s `_run` timeout surfaces as
GitCommandError 124, or any nonzero git failure) can leave a partial
checkout at `repo_dir` and/or a dangling pool worktree registration. Left
behind, the event retry hits stale metadata and fails again on the same
path. Best-effort remove the checkout and prune the pool, then re-raise so the
retry starts from a clean path. If the prune itself fails (incl. a 124
timeout), raise that instead — chained from the add error — since a
dangling registration left behind is exactly what poisons the retry.
"""
try:
_run(add_cmd, cwd=pool)
except GitCommandError as add_err:
shutil.rmtree(repo_dir, ignore_errors=True)
pruned = _safe_run(["git", "worktree", "prune"], cwd=pool)
if pruned.returncode != 0:
raise GitCommandError(
["git", "worktree", "prune"], pruned.returncode, pruned.stdout, pruned.stderr
) from add_err
raise
_SHARED_OMP_GID = 2000
def _slot_permissions_active(slot_uid: int | None) -> bool:
return slot_uid is not None and platform.system() == "Linux" and os.geteuid() == 0
def _slot_pids(slot_uid: int, proc_root: Path = Path("/proc")) -> tuple[int, ...]:
"""Return non-zombie process ids owned by the slot UID.
Debian's slim image does not include procps/pkill. Reading `/proc` keeps
slot cleanup self-contained and avoids adding a runtime package only for
this one operation.View on GitHub (pinned to 9690622007)
Solutions
- Fix pool metadata: run `git worktree prune -v` manually in the pool clone and inspect `.git/worktrees/` for corrupt entries; delete bogus subdirectories.
- Check permissions/ownership of the pool directory (slot_uid GID sharing) — prune must be able to write the pool's .git.
- Remove the stale repo_dir and the whole workspace root, then retry so ensure_clone/ensure_workspace rebuild state.
- Escalate to recreating the pool clone (delete pool dir; ensure_clone re-clones) if metadata stays corrupt.
Example fix
# before # event stuck failing with chained prune error # after # operator recovery inside the pool subprocess.run(["git", "worktree", "prune", "-v"], cwd=pool) shutil.rmtree(ws_root, ignore_errors=True) ws = manager.ensure_workspace(...) # rebuilds clean
Defensive patterns
Strategy: try-catch
Validate before calling
chk = subprocess.run(["git","worktree","prune","--dry-run"], cwd=pool, capture_output=True) metadata_ok = chk.returncode == 0
Try / catch
try:
ws = manager.ensure_workspace(...)
except GitCommandError as e:
if "worktree prune" in str(getattr(e, 'cmd', '')):
alert_operator_pool_corrupt(pool) # needs manual .git/worktrees repair
else:
schedule_retry(event) Prevention
- Never mutate the pool clone's .git by hand or with external tools.
- Run git as the same user/GID (slot_uid) that robomp uses, so prune can write pool metadata.
- After hard kills, run `git worktree prune -v` in the pool proactively.
When it happens
Trigger: ensure_workspace / ensure_release_workspace hitting a worktree add failure (existing dir, taken branch) where the follow-up `git worktree prune` also exits nonzero — typically because the pool clone's .git/worktrees metadata is corrupt, the pool dir was concurrently mutated, or permissions/locks block the prune.
Common situations: A previous git process crashed mid-worktree-registration leaving malformed .git/worktrees entries; the shared pool clone was modified by hand or by another tool; running with a slot_uid whose filesystem permissions cannot write the pool metadata.
Related errors
- GitCommandError: git worktree prune failed (incl. 124 timeou
- Isolated subagent execution could not be prepared: ${message
- could not find an unused worktree path under ${basePath} (tr
- GitCommandError: git command failed (nonzero exit)
- GitCommandError: git checkout --detach failed (nonzero exit)
AI-assisted analysis of can1357/oh-my-pi@9690622007 (2026-08-31).
Data as JSON: /api/errors/6cd870f1a49098b0.
Report an issue: GitHub.