astral-sh/ruff · error
project directory ` ` does not contain a base name
Error message
project directory `{project_path}` does not contain a base name What it means
Task::new in ty_completion_eval requires the project directory path to end with a real directory name. It calls SystemPath::file_name() and fails when the path is empty or terminates in `..` or `/` with no final component, because the directory name is used as the human-readable task name.
Solutions
- Point the task's project_path at the actual fixture directory (e.g. crates/ty_completion_eval/truth/<fixture>), not the root or a parent
- Remove any trailing `..` or `/` segments from the configured path
- Use SystemPath::from_path with an absolute, non-root directory path and verify file_name() succeeds before calling Task::new
Example fix
// before
let task = Task::new(&SystemPath::from("..").unwrap(), &truth, cursor)?;
// after
let project = std::path::PathBuf::from("crates/ty_completion_eval/truth/my-project").canonicalize()?;
let task = Task::new(&SystemPath::from_std_path(&project).unwrap(), &truth, cursor)?; Defensive patterns
Strategy: validation
Validate before calling
fn validate_project_path(p: &SystemPath) -> Result<(), String> {
match p.file_name() {
Some(_) if p.as_std_path().is_dir() => Ok(()),
Some(_) => Err(format!("`{}` is not a directory", p.display())),
None => Err(format!("`{}` has no base name (empty, root, or `..`)", p.display())),
}
} Type guard
fn has_base_name(p: &SystemPath) -> bool {
p.file_name().is_some()
} Try / catch
match Task::new(&project_path, &truth, cursor) {
Ok(task) => run(task),
Err(e) if e.to_string().contains("does not contain a base name") => {
eprintln!("project_path must be a concrete fixture directory: {e}");
std::process::exit(2);
}
Err(e) => return Err(e),
} Prevention
- Always pass an absolute, canonicalized directory with a real final component
- Never build paths by joining with `..`; canonicalize instead
- Check SystemPath::file_name() in setup code before launching an evaluation run
When it happens
Trigger: Calling Task::new with a SystemPath built from "/", ".", "foo/..", or a path that normalizes to the filesystem root; also paths constructed by joining that end with a trailing separator resolving to root.
Common situations: A completion-evaluation task CSV or fixture path is misconfigured to point at the repository root or a parent directory; a path was built with an erroneous trailing `..`; an empty path from environment/config substitution.
Related errors
- truth source directory
- could not find any ` ` directives in any of the files in
- Expected to handle named fields
- invalid default warning pattern
- path ` ` is not valid UTF-8
AI-assisted analysis of astral-sh/ruff@5bb508f594 (2026-09-05).
Data as JSON: /api/errors/09eb205e7c3ed90d.
Report an issue: GitHub.
Appendix: source
Thrown at crates/ty_completion_eval/src/main.rs:277
db: ProjectDatabase,
dir: SystemPathBuf,
name: String,
cursor: Cursor,
settings: ty_ide::CompletionSettings,
}
impl Task {
/// Create a new task for the Python project at `project_path`.
///
/// `truth` should correspond to the completion configuration and the
/// expected answer for completions at the given `cursor` position.
fn new(
project_path: &SystemPath,
truth: &CompletionTruth,
cursor: Cursor,
) -> anyhow::Result<Task> {
let name = project_path.file_name().ok_or_else(|| {
anyhow::anyhow!("project directory `{project_path}` does not contain a base name")
})?;
let system = OsSystem::new(project_path);
let mut project_metadata = ProjectMetadata::discover(project_path, &system)?;
// Explicitly point ty to the .venv to avoid any set VIRTUAL_ENV variable to take precedence.
project_metadata.set_override_options(Options {
environment: Some(EnvironmentOptions {
python: Some(RelativePathBuf::cli(".venv")),
..EnvironmentOptions::default()
}),
..Options::default()
});
let db = ProjectDatabase::fallible(project_metadata, system)?;
Ok(Task {
db,
dir: project_path.to_path_buf(),
name: name.to_string(),
cursor,View on GitHub (pinned to 5bb508f594)