{"record":{"id":"02b142eef365a479","repo":"astral-sh/ruff","slug":"path-is-not-valid-utf-8","errorCode":null,"errorMessage":"path `{}` is not valid UTF-8","messagePattern":"path `(.+?)` is not valid UTF-8","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ty_completion_eval/src/main.rs","lineNumber":561,"sourceCode":"fn copy_project(src_dir: &SystemPath, dst_dir: &SystemPath) -> anyhow::Result<Vec<Cursor>> {\n    std::fs::create_dir_all(dst_dir).with_context(|| dst_dir.to_string())?;\n\n    let mut cursors = vec![];\n    let it = walkdir::WalkDir::new(src_dir.as_std_path())\n        .sort_by_file_name()\n        .into_iter()\n        .filter_entry(|dent| {\n            !dent\n                .file_name()\n                .to_str()\n                .is_some_and(|name| name.starts_with('.'))\n        });\n    for result in it {\n        let dent =\n            result.with_context(|| format!(\"failed to get directory entry from {src_dir}\"))?;\n\n        let src = SystemPath::from_std_path(dent.path()).ok_or_else(|| {\n            anyhow::anyhow!(\"path `{}` is not valid UTF-8\", dent.path().display())\n        })?;\n        let name = src\n            .strip_prefix(src_dir)\n            .expect(\"descendent of `src_dir` must start with `src`\");\n        // let name = src\n        // .file_name()\n        // .ok_or_else(|| anyhow::anyhow!(\"path `{src}` is missing a basename\"))?;\n        let dst = dst_dir.join(name);\n        if dent.file_type().is_dir() {\n            std::fs::create_dir_all(dst.as_std_path())\n                .with_context(|| format!(\"failed to create directory `{dst}`\"))?;\n        } else {\n            cursors.extend(copy_file(src, &dst)?);\n        }\n    }\n    anyhow::ensure!(\n        !cursors.is_empty(),\n        \"could not find any `<CURSOR>` directives in any of the files in `{src_dir}`\",","sourceCodeStart":543,"sourceCodeEnd":579,"githubUrl":"https://github.com/astral-sh/ruff/blob/672bb4edf04c84f8b0753346359daee4057158f2/crates/ty_completion_eval/src/main.rs#L543-L579","documentation":"While copying a fixture's files into the eval temp directory, the walk converts every visited entry to a `SystemPath`; any file or directory inside the fixture whose name is not valid UTF-8 aborts with this message and the path echoed. Dot-prefixed entries are filtered out before this, so hidden dirs like `.venv` are not the cause.","triggerScenarios":"A non-UTF-8-named file or directory inside a truth fixture project — build droppings, cache files, or extraction residue — encountered during the recursive copy from `truth/` into the temp eval dir.","commonSituations":"Fixtures that once held real project artifacts (`.tox`, caches with byte names); files synced from Windows with mangled encodings; fuzzing residue committed accidentally.","solutions":["Detect offenders: `find <fixture-dir> -print0 | while IFS= read -r -d '' f; do printf '%s' \"$f\" | iconv -f utf-8 -t utf-8 >/dev/null 2>&1 || echo \"non-UTF-8: $f\"; done`","Delete or rename the reported paths, and keep fixtures to committed files only (`git status` / `git clean` on the fixture)","Review what created the file and disable it for the truth tree (e.g. run builds outside the fixtures)"],"exampleFix":"# before: run aborts with `path ... is not valid UTF-8`\n# after: clean the fixture, then re-run\ngit clean -fdx crates/ty_completion_eval/truth/<fixture>\ncargo run -p ty_completion_eval -- all","handlingStrategy":"validation","validationCode":"find crates/ty_completion_eval/truth -print0 \\\n| while IFS= read -r -d '' f; do\n    printf '%s' \"$f\" | iconv -f utf-8 -t utf-8 >/dev/null 2>&1 \\\n      || echo \"non-UTF-8 path: $f\" >&2\n  done","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Keep fixtures to committed files only; run builds outside the truth tree","`git clean -fdx` fixtures before eval runs","Never sync or build inside truth fixtures"],"tags":["unicode","evaluation","paths","repo-hygiene"],"backgroundTag":null,"analyzedSha":"672bb4edf04c84f8b0753346359daee4057158f2","analyzedAt":"2026-08-16T08:54:05.464Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}