xai-org/grok-build · error

failed to create BTRFS snapshot from {} to {}: {}

Error message

failed to create BTRFS snapshot from {} to {}: {}

What it means

`create_snapshot` shells out to `btrfs subvolume snapshot <source> <dest>`; when the command exits non-zero it bails with this message including the source, dest, and btrfs stderr. It means the btrfs tool itself refused or failed the snapshot, not a Rust-side error.

Source

Thrown at crates/codegen/xai-fast-worktree/src/btrfs/snapshot.rs:40

        dest = %dest.display(),
        "creating BTRFS snapshot"
    );

    let mut cmd = Command::new("btrfs");
    xai_tty_utils::detach_std_command(&mut cmd);
    cmd.stdin(Stdio::null());
    // OsStr args: a non-UTF-8 path must not silently collapse to ".".
    let output = cmd
        .arg("subvolume")
        .arg("snapshot")
        .arg(source)
        .arg(dest)
        .output()
        .with_context(|| "failed to execute btrfs subvolume snapshot command")?;

    if !output.status.success() {
        let stderr = String::from_utf8_lossy(&output.stderr);
        bail!(
            "failed to create BTRFS snapshot from {} to {}: {}",
            source.display(),
            dest.display(),
            stderr.trim()
        );
    }

    tracing::debug!(
        dest = %dest.display(),
        "BTRFS snapshot created successfully"
    );

    Ok(())
}

/// Result of creating a snapshot for a worktree.
#[derive(Debug)]
pub struct SnapshotResult {

View on GitHub (pinned to bc7f02eddd)

Solutions

  1. Read the stderr appended to the error — it contains btrfs's actual reason (e.g. 'not a btrfs subvolume', 'already exists').
  2. Verify the source is a btrfs subvolume: `btrfs subvolume show <source>` must succeed.
  3. Ensure both source and dest live on btrfs filesystems and dest does not already exist.
  4. Run with sufficient privileges (root or CAP_SYS_ADMIN) and confirm the `btrfs` binary is installed in the environment/container.
  5. If the environment isn't btrfs, use a non-btrfs worktree backend instead of forcing snapshots.

Example fix

// before
// running on ext4:
create_snapshot(Path::new("/home/user/repo"), Path::new("/home/user/repo-snap"))?;
// after
// pick a btrfs-backed location and verify first
if btrfs::is_btrfs(Path::new("/mnt/btrfs/repo")) {
    create_snapshot(Path::new("/mnt/btrfs/repo"), Path::new("/mnt/btrfs/repo-snap"))?;
} else {
    // fall back to plain copy-based worktree creation
}
Defensive patterns

Strategy: validation

Validate before calling

use std::process::Command;
fn is_btrfs_subvolume(p: &std::path::Path) -> bool {
    Command::new("btrfs").args(["subvolume", "show"])
        .arg(p).output().map(|o| o.status.success()).unwrap_or(false)
}
assert!(is_btrfs_subvolume(&source), "source must be a btrfs subvolume");
assert!(!dest.exists(), "snapshot dest must not already exist");

Try / catch

match create_snapshot(&src, &dst) {
    Err(e) if e.to_string().contains("failed to create BTRFS snapshot") => {
        eprintln!("btrfs refused: {e}"); // stderr is embedded — log it
        fallback_to_copy_worktree(&src, &dst)?;
    }
    r => r?,
}

Prevention

When it happens

Trigger: Calling `create_snapshot` (directly or via `create_snapshot_with_symlink` / `create_overlay_worktree`) where source doesn't exist or isn't a btrfs subvolume, dest already exists, or the filesystem at source/dest isn't btrfs.

Common situations: Trying to snapshot on ext4/xfs/tmpfs volumes; snapshotting a plain directory instead of a subvolume; dest path already existing; running inside a container without btrfs kernel support or without `btrfs` binary; insufficient privileges (non-root, missing CAP_SYS_ADMIN).

Related errors


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