{"id":"298f41657629dfcf","repo":"rust-lang/cargo","slug":"character-at-line-is-invalid-cargo-only-suppor","errorCode":null,"errorMessage":"Character at line {} is invalid. Cargo only supports UTF-8.","messagePattern":"Character at line (.+?) is invalid\\. Cargo only supports UTF-8\\.","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"src/ops/cargo_new.rs","lineNumber":660,"sourceCode":"            VersionControl::Fossil => &self.fossil_ignore,\n            _ => &self.ignore,\n        };\n\n        ignore_items.join(\"\\n\") + \"\\n\"\n    }\n\n    /// `format_existing` is used to format the `IgnoreList` when the ignore file\n    /// already exists. It reads the contents of the given `BufRead` and\n    /// checks if the contents of the ignore list are already existing in the\n    /// file.\n    fn format_existing<T: BufRead>(&self, existing: T, vcs: VersionControl) -> CargoResult<String> {\n        let mut existing_items = Vec::new();\n        for (i, item) in existing.lines().enumerate() {\n            match item {\n                Ok(s) => existing_items.push(s),\n                Err(err) => match err.kind() {\n                    ErrorKind::InvalidData => {\n                        return Err(anyhow!(\n                            \"Character at line {} is invalid. Cargo only supports UTF-8.\",\n                            i\n                        ));\n                    }\n                    _ => return Err(anyhow!(err)),\n                },\n            }\n        }\n\n        let ignore_items = match vcs {\n            VersionControl::Hg => &self.hg_ignore,\n            VersionControl::Fossil => &self.fossil_ignore,\n            _ => &self.ignore,\n        };\n\n        let mut out = String::new();\n\n        // Fossil does not support `#` comments.","sourceCodeStart":642,"sourceCodeEnd":678,"githubUrl":"https://github.com/rust-lang/cargo/blob/0e07a155371a6ce88ae53a2c00df940280c09a67/src/ops/cargo_new.rs#L642-L678","documentation":"While merging Cargo's ignore entries into an existing .gitignore/.hgignore/.ignore during `cargo new`/`cargo init`, IgnoreList::format_existing reads the file line-by-line as UTF-8. If a byte sequence is not valid UTF-8, the BufRead returns ErrorKind::InvalidData and Cargo surfaces this message naming the offending line number. Cargo only writes/manages UTF-8 ignore files.","triggerScenarios":"`cargo init` (or `cargo new` into a dir) where the existing `.gitignore`/`.hgignore`/`.ignore` contains non-UTF-8 bytes - e.g. Latin-1 accented characters, a stray binary blob, or a file written by a tool that used the system codepage.","commonSituations":"Checkouts on Windows where the editor saved .gitignore as UTF-16 or with BOM+CRLF corruption; copy-pasted ignore content from a non-UTF-8 source; files touched by a misbehaving sed/iconv; legacy repos with mojibake.","solutions":["Re-encode the offending ignore file to UTF-8: `iconv -f LATIN1 -t UTF-8 .gitignore -o .gitignore`","Open the file in an editor, fix or remove the invalid characters, and save as UTF-8","Delete the ignore file and let Cargo regenerate it from scratch"],"exampleFix":"# before: .gitignore contains non-UTF-8 bytes -> error\n# after\niconv -f LATIN1 -t UTF-8 .gitignore -o .gitignore.utf8 && mv .gitignore.utf8 .gitignore\ncargo init","handlingStrategy":"validation","validationCode":"use std::path::Path;\nfn ensure_ignore_utf8(path: &Path) -> Result<(), String> {\n    let bytes = std::fs::read(path).map_err(|e| e.to_string())?;\n    std::str::from_utf8(&bytes).map(|_| ()).map_err(|_| format!(\"{} is not valid UTF-8\", path.display()))\n}\n\nfor f in [\".gitignore\", \".hgignore\", \".ignore\"] { ensure_ignore_utf8(Path::new(f))?; }","typeGuard":"import { readFileSync } from 'fs';\nfunction isValidUtf8(path: string): boolean {\n  try { new TextDecoder('utf-8', { fatal: true }).decode(readFileSync(path)); return true; }\n  catch { return false; }\n}","tryCatchPattern":null,"preventionTips":["Configure editors/git to write .gitignore as UTF-8 without BOM","Audit ignore files for non-ASCII bytes before running cargo init","Add a pre-commit hook rejecting non-UTF-8 ignore files"],"tags":["vcs","encoding","utf-8","ignore-file"],"analyzedSha":"0e07a155371a6ce88ae53a2c00df940280c09a67","analyzedAt":"2026-08-06T01:46:58.334Z","schemaVersion":2}