aaif-goose/goose · error

git diff --stat returned non-UTF8 output: {e}

Error message

git diff --stat returned non-UTF8 output: {e}

What it means

Identical guard to the diff collector but for the stat pass: `git diff --stat` output must decode as valid UTF-8 (String::from_utf8), and any non-UTF8 bytes — typically unescaped non-ASCII filenames — abort stat collection with this error.

Source

Thrown at crates/goose-cli/src/commands/review/handler.rs:447

        None => {
            cmd.arg("HEAD");
        }
    }
    if !files.is_empty() {
        cmd.arg("--");
        for f in files {
            cmd.arg(f);
        }
    }
    let out = cmd.output().context("git diff --stat failed")?;
    if !out.status.success() {
        bail!(
            "git diff --stat failed: {}",
            String::from_utf8_lossy(&out.stderr)
        );
    }
    String::from_utf8(out.stdout)
        .map_err(|e| anyhow!("git diff --stat returned non-UTF8 output: {e}"))
}

/// List untracked-but-not-ignored files in `repo_root`. Used to expose
/// brand-new files to the review when no `--range` is given (default
/// `git diff HEAD` would silently drop them).
fn untracked_files(repo_root: &UntrackedRoot, files: &[String]) -> Result<Vec<String>> {
    let mut cmd = untracked_git_command(repo_root)?;
    cmd.args(["ls-files", "--others", "--exclude-standard"]);
    if !files.is_empty() {
        cmd.arg("--");
        for f in files {
            cmd.arg(f);
        }
    }
    let out = cmd.output().context("git ls-files failed")?;
    if !out.status.success() {
        bail!(
            "git ls-files failed: {}",

View on GitHub (pinned to 3810898a74)

Solutions

  1. Set `git config core.quotepath true` so git escapes non-ASCII path bytes
  2. Limit reviewed files to UTF-8-named paths via `--files`
  3. Rename non-UTF8 filenames to valid UTF-8
  4. Mark binary files in .gitattributes to keep stat output clean

Example fix

# before
goose review                    # --stat output non-UTF8 -> error

# after
git config core.quotepath true
goose review
Defensive patterns

Strategy: validation

Validate before calling

# Pre-check the stat pass specifically
git diff --stat HEAD | iconv -f UTF-8 -t UTF-8 > /dev/null 2>&1 \
  || echo 'git diff --stat output is not valid UTF-8: fix filenames or set core.quotepath=true'

Try / catch

// Rust (own tooling): accept lossy decoding for stat output used only for display
let stat = String::from_utf8_lossy(&out.stdout).into_owned();

Prevention

When it happens

Trigger: Running `goose review` when `git diff --stat` emits non-UTF8 bytes, e.g. non-ASCII filenames not quoted/escaped by git, or corrupted refs producing odd output.

Common situations: Same class as the diff variant: legacy filename encodings, mixed-OS teams, core.quotepath disabled by default in some setups.

Related errors


AI-assisted analysis of aaif-goose/goose@3810898a74 (2026-08-16). Data as JSON: /api/errors/4de1b9456d189742. Report an issue: GitHub.