{"record":{"id":"8502ae0ae214c393","repo":"astral-sh/ruff","slug":"truth-source-directory-dir-does-not-contain-a","errorCode":null,"errorMessage":"truth source directory `{dir}` does not contain a base name","messagePattern":"truth source directory `(.+?)` does not contain a base name","errorType":"console","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/ty_completion_eval/src/main.rs","lineNumber":432,"sourceCode":"\n            let dir = SystemPath::from_std_path(&path).ok_or_else(|| {\n                anyhow::anyhow!(\n                    \"truth source directory `{path}` contains invalid UTF-8\",\n                    path = path.display()\n                )\n            })?;\n            sources.push(TaskSource::new(dir)?);\n        }\n        // Sort our sources so that we always run in the same order.\n        // And also so that the CSV output is deterministic across\n        // all platforms.\n        sources.sort_by(|source1, source2| source1.name.cmp(&source2.name));\n        Ok(sources)\n    }\n\n    fn new(dir: &SystemPath) -> anyhow::Result<TaskSource> {\n        let name = dir.file_name().ok_or_else(|| {\n            anyhow::anyhow!(\"truth source directory `{dir}` does not contain a base name\")\n        })?;\n\n        let truth_path = dir.join(\"completion.toml\");\n        let truth_data = std::fs::read(truth_path.as_std_path())\n            .with_context(|| format!(\"failed to read truth data at `{truth_path}`\"))?;\n        let truth = toml::from_slice(&truth_data).with_context(|| {\n            format!(\"failed to parse TOML completion truth data from `{truth_path}`\")\n        })?;\n\n        Ok(TaskSource {\n            dir: dir.to_path_buf(),\n            name: name.to_string(),\n            truth,\n        })\n    }\n\n    /// Convert this \"source\" task (from the Ruff repository) into\n    /// one or more evaluation tasks within a single Python project.","sourceCodeStart":414,"sourceCodeEnd":450,"githubUrl":"https://github.com/astral-sh/ruff/blob/5bb508f59481c1a02d5c7ff8568b9ffd8a763eef/crates/ty_completion_eval/src/main.rs#L414-L450","documentation":"TaskSource::new derives the source's name from the directory's base name via SystemPath::file_name(). This error is thrown when the truth source directory path has no final component (empty path or ends in `..`/root), because a deterministic name is required for the completion-evaluation task set.","triggerScenarios":"Calling TaskSource::new with a SystemPath of \"/\", \".\", \"foo/..\" or otherwise lacking a final component; typically reached through TaskSource::all only if a scan entry normalizes to such a path.","commonSituations":"A misconfigured truth root (empty TRUTH_DIR env var collapsing the join), or code passing the truth root itself instead of a child directory.","solutions":["Pass a concrete truth source subdirectory (one containing completion.toml), not the root or an empty path","Check that the environment variable/argument supplying the truth directory is set and non-empty","Canonicalize the directory and confirm file_name() is Some before constructing the TaskSource"],"exampleFix":"// before\nlet src = SystemPath::from(env::var(\"TRUTH_DIR\").unwrap_or_default());\nTaskSource::new(&src)?;\n// after\nlet src = SystemPathBuf::from_path_buf(std::env::current_dir()?.join(\"crates/ty_completion_eval/truth/my-fixture\")).unwrap();\nassert!(src.file_name().is_some());\nTaskSource::new(&src)?;","handlingStrategy":"validation","validationCode":"fn validate_task_source(dir: &SystemPath) -> Result<(), String> {\n    if dir.file_name().is_none() {\n        return Err(format!(\"`{}` must be a named subdirectory\", dir.display()));\n    }\n    if !dir.join(\"completion.toml\").as_std_path().exists() {\n        return Err(format!(\"`{}` is missing completion.toml\", dir.display()));\n    }\n    Ok(())\n}","typeGuard":"fn is_named_dir(p: &SystemPath) -> bool {\n    p.file_name().is_some()\n}","tryCatchPattern":"match TaskSource::new(&dir) {\n    Ok(src) => src,\n    Err(e) if e.to_string().contains(\"does not contain a base name\") => {\n        eprintln!(\"pass a concrete truth subdirectory, not the root: {e}\");\n        std::process::exit(2);\n    }\n    Err(e) => return Err(e),\n}","preventionTips":["Guard the directory env var/argument for emptiness before building the path","Always point at a fixture subdirectory containing completion.toml","Canonicalize the path and assert file_name() is Some in setup"],"tags":["rust","path","configuration","completion-eval"],"backgroundTag":"invalid-path-base-name","analyzedSha":"5bb508f59481c1a02d5c7ff8568b9ffd8a763eef","analyzedAt":"2026-09-05T10:32:37.492Z","contentChangedAt":"2026-09-05T10:32:37.492Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}