nikivdev/code · error

Refusing to commit generated files

Error message

Refusing to commit generated files

What it means

The tool scans staged files (git diff --cached --name-status) against a policy of unwanted/generated paths (e.g. .beads/, lockfiles, build artifacts) and aborts the commit if any match. It prints remediation guidance (f gitignore policy-init / fix) and allows override with FLOW_ALLOW_UNWANTED_COMMIT=1.

Source

Thrown at src/commit.rs:6698

    for (path, _) in &staged {
        let _ = git_run_in(repo_root, &["reset", "HEAD", "--", path]);
    }

    if !ignore_entries.is_empty() {
        println!("Added ignore rules for generated files and unstaged them.");
    } else {
        println!("Unstaged generated files.");
    }
    if saw_personal_tooling {
        println!(
            "Personal tooling paths (.beads/) should be ignored globally, not in project .gitignore."
        );
        println!("Run `f gitignore policy-init` and `f gitignore fix` to clean existing repos.");
    }
    println!("Re-run `f commit` after verifying the changes.");
    println!("Set FLOW_ALLOW_UNWANTED_COMMIT=1 to override.");
    bail!("Refusing to commit generated files");
}
fn unwanted_staged_paths(repo_root: &Path) -> Vec<(String, String)> {
    let output = Command::new("git")
        .args(["diff", "--cached", "--name-status", "-z"])
        .current_dir(repo_root)
        .output();

    let Ok(output) = output else {
        return Vec::new();
    };
    if !output.status.success() {
        return Vec::new();
    }

    let mut out = Vec::new();
    let raw = String::from_utf8_lossy(&output.stdout);
    let parts: Vec<&str> = raw.split('\0').collect();
    let mut i = 0;

View on GitHub (pinned to a747e741ae)

Solutions

  1. Unstage the listed paths: `git restore --staged <path>`
  2. Run `f gitignore policy-init` and `f gitignore fix` to set up correct ignore rules
  3. Regenerate ignored artifacts locally instead of committing them
  4. Set FLOW_ALLOW_UNWANTED_COMMIT=1 only if committing the generated files is intentional

Example fix

// before (shell)
git add . && f commit   # build/dist artifacts staged
// after (shell)
printf 'dist/\n.beads/\n' >> .gitignore && git rm -r --cached dist .beads && f commit
Defensive patterns

Strategy: validation

Validate before calling

let out = Command::new("git")
    .args(["diff", "--cached", "--name-only"])
    .output()?;
let unwanted = [".beads/", "dist/", "build/"];
let staged = String::from_utf8_lossy(&out.stdout);
let bad: Vec<&str> = staged.lines()
    .filter(|p| unwanted.iter().any(|u| p.starts_with(u)))
    .collect();
if !bad.is_empty() { eprintln!("unstage generated files: {:?}", bad); }

Try / catch

if let Err(e) = tool.commit(msg) {
    if e.to_string().contains("generated files") {
        eprintln!("run `f gitignore policy-init` and `f gitignore fix`, then re-stage");
    } else { return Err(e.into()); }
}

Prevention

When it happens

Trigger: Running `f commit` with generated artifacts or personal-tooling paths staged, detected by unwanted_staged_paths() — e.g. a .beads/ directory staged, or unwanted paths listed in project .gitignore instead of global gitignore.

Common situations: `git add .` picking up build output or generated files, .beads/ accidentally tracked because it was committed before being ignored, gitignore policy not initialized in a new repo, or generated files newly appearing after a build.

Related errors


AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01). Data as JSON: /api/errors/7b65fb6c10e2d0d6. Report an issue: GitHub.