xai-org/grok-build · error

daemon RemoveWorktree failed

Error message

daemon RemoveWorktree failed: {e}

What it means

remove_nfs_worktree first asks the grove daemon to remove the worktree via client.remove_worktree. If the daemon accepts the ping but the RemoveWorktree RPC returns an error, this wraps and surfaces it as 'daemon RemoveWorktree failed', aborting the local remove path.

Solutions

  1. Inspect the inner error (source chain) — usually EBUSY/permission — and close processes using the mount, then retry
  2. Check daemon logs for the RemoveWorktree failure reason
  3. Restart the daemon to clear stale state, then retry try_nfs_remove
  4. Fall back to the manual path: umount the dest, verify unmounted, then remove backing yourself

Example fix

// before
try_nfs_remove(&path)?;
// after
if let Err(e) = try_nfs_remove(&path) {
    eprintln!("daemon remove failed: {e:#}");
    Command::new("umount").arg(&path).status()?;
    // verify unmounted, then remove backing dir manually
}
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure no processes hold the mount before daemon removal
let busy = Command::new("fuser").arg("-m").arg(&path)
    .stdout(Stdio::null()).status().map(|s| s.success());
if busy == Ok(true) { eprintln!("mount is busy; close processes first"); }

Try / catch

match client.remove_worktree(worktree_path, false) {
    Ok(()) => {}
    Err(e) => {
        eprintln!("RemoveWorktree failed: {e:#}"); // inspect source chain for EBUSY/EACCES
        // fall back to manual umount + verified removal
    }
}

Prevention

When it happens

Trigger: Calling try_nfs_remove while the daemon is up but its remove_worktree fails: dest busy/EBUSY, backing dir missing, permission denied, worktree id lookup failed, or daemon-side unmount rejected.

Common situations: A process still holds files open under the mount (EBUSY); daemon lost track of the worktree after a config change; running the remove as a different user than the daemon.

Related errors


AI-assisted analysis of xai-org/grok-build@bc7f02eddd (2026-08-31). Data as JSON: /api/errors/1b2e8065e9e9c1b9. Report an issue: GitHub.

Appendix: source

Thrown at crates/codegen/xai-fast-worktree/src/nfs/remove.rs:42

        if lookup_from_markers(worktree_path).is_none() {
            bail!(
                "{} is a live grove mount without a backing marker; refusing rm -rf",
                worktree_path.display()
            );
        }
    } else if dest_is_mountpoint(worktree_path) || lookup_nfs_meta(worktree_path).is_none() {
        return Ok(None);
    }
    remove_nfs_worktree(worktree_path)
}
fn remove_nfs_worktree(worktree_path: &Path) -> Result<Option<RemoveReport>> {
    let opts = nfs_opts_from_env_and_meta(None);
    let client = NfsWorktreeClient::from_opts(&opts);
    if client.ping() {
        match client.remove_worktree(worktree_path, false) {
            Ok(()) => return report_after_daemon_unmount(worktree_path),
            Err(e) => {
                bail!("daemon RemoveWorktree failed: {e}");
            }
        }
    }
    if dest_is_mountpoint(worktree_path) {
        if lookup_from_markers(worktree_path).is_none() {
            bail!(
                "{} is still a mountpoint without a grove marker; refusing umount/rm",
                worktree_path.display()
            );
        }
        plain_umount(worktree_path)?;
    }
    if !super::dest_is_known_unmounted(worktree_path) {
        bail!(
            "unmount of {} could not be verified (still mounted or mount table \
             inconclusive); retaining backing and pin",
            worktree_path.display()
        );

View on GitHub (pinned to bc7f02eddd)