{"record":{"id":"9ef716c09997e24f","repo":"aaif-goose/goose","slug":"git-diff-returned-non-utf8-output-e","errorCode":null,"errorMessage":"git diff returned non-UTF8 output: {e}","messagePattern":"git diff returned non-UTF8 output: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/goose-cli/src/commands/review/handler.rs","lineNumber":419,"sourceCode":"    match range {\n        Some(r) => {\n            cmd.arg(r);\n        }\n        None => {\n            cmd.arg(\"HEAD\");\n        }\n    }\n    if !files.is_empty() {\n        cmd.arg(\"--\");\n        for f in files {\n            cmd.arg(f);\n        }\n    }\n    let out = cmd.output().context(\"git diff failed\")?;\n    if !out.status.success() {\n        bail!(\"git diff failed: {}\", String::from_utf8_lossy(&out.stderr));\n    }\n    String::from_utf8(out.stdout).map_err(|e| anyhow!(\"git diff returned non-UTF8 output: {e}\"))\n}\n\nfn collect_diff_stat(repo_root: &Path, range: Option<&str>, files: &[String]) -> Result<String> {\n    let mut cmd = review_git_command(repo_root);\n    cmd.arg(\"diff\").arg(\"--stat\");\n    match range {\n        Some(r) => {\n            cmd.arg(r);\n        }\n        None => {\n            cmd.arg(\"HEAD\");\n        }\n    }\n    if !files.is_empty() {\n        cmd.arg(\"--\");\n        for f in files {\n            cmd.arg(f);\n        }","sourceCodeStart":401,"sourceCodeEnd":437,"githubUrl":"https://github.com/aaif-goose/goose/blob/3810898a7447ec3299be72e223d3570a7aabf0ab/crates/goose-cli/src/commands/review/handler.rs#L401-L437","documentation":"The review command shells out to `git diff` and requires its stdout to be valid UTF-8 (String::from_utf8 on out.stdout). Repos whose diff output contains non-UTF8 bytes — typically filenames in legacy encodings or binary content leaking into hunks — fail the conversion and abort diff collection.","triggerScenarios":"Running `goose review` on a repo where the diff includes files whose names contain non-UTF8 bytes (e.g. latin-1 encoded paths) or binary blobs whose raw bytes appear in the diff output.","commonSituations":"Repos with legacy filename encodings; accidental binary commits; cross-platform checkouts on macOS/Windows producing oddly named files; unquoted non-ASCII paths in git output.","solutions":["Scope the review to known text paths: `goose review --files 'src/**'`","Set `git config core.quotepath true` so git escapes non-ASCII path bytes in output","Rename offending files to valid UTF-8 names","Mark binaries in .gitattributes (e.g. `*.bin binary`) so git omits their content from diffs"],"exampleFix":"# before\ngoose review                    # non-UTF8 filename in diff -> error\n\n# after\ngit config core.quotepath true\ngoose review --files 'src/**/*.rs'","handlingStrategy":"validation","validationCode":"# Pre-check that the diff decodes as UTF-8 before reviewing\ngit diff HEAD | iconv -f UTF-8 -t UTF-8 > /dev/null 2>&1 \\\n  || echo 'git diff output is not valid UTF-8: fix filenames or set core.quotepath=true'","typeGuard":null,"tryCatchPattern":"// Rust (own tooling): accept lossy decoding when output is display-only\nlet diff = String::from_utf8_lossy(&out.stdout).into_owned();","preventionTips":["Keep repository filenames valid UTF-8","Mark binary files in .gitattributes","Enable core.quotepath on mixed-OS teams"],"tags":["review","git","encoding","utf-8","filesystem"],"backgroundTag":null,"analyzedSha":"3810898a7447ec3299be72e223d3570a7aabf0ab","analyzedAt":"2026-08-16T10:14:26.282Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}