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
- Unstage the listed paths: `git restore --staged <path>`
- Run `f gitignore policy-init` and `f gitignore fix` to set up correct ignore rules
- Regenerate ignored artifacts locally instead of committing them
- 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
- Initialize gitignore policy in every repo (`f gitignore policy-init`)
- Put personal tooling paths in global gitignore, not project .gitignore
- Check `git diff --cached --name-status` before committing
- Never set FLOW_ALLOW_UNWANTED_COMMIT=1 in CI defaults
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
- Refusing to commit internal .ai files
- jj git export retry loop should always return
- Lin.app is not running
- No branches available to search
- No branches matched query '{}'.
AI-assisted analysis of nikivdev/code@a747e741ae (2026-09-01).
Data as JSON: /api/errors/7b65fb6c10e2d0d6.
Report an issue: GitHub.