{"record":{"id":"a05df51ee49295b6","repo":"astral-sh/ruff","slug":"provided-project-path-project-is-not-a-directo","errorCode":null,"errorMessage":"Provided project path `{project}` is not a directory","messagePattern":"Provided project path `(.+?)` is not a directory","errorType":"console","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/ty/src/lib.rs","lineNumber":123,"sourceCode":"    let cwd = {\n        let cwd = std::env::current_dir().context(\"Failed to get the current working directory\")?;\n        SystemPathBuf::from_path_buf(cwd).map_err(|path| {\n            anyhow!(\n                \"The current working directory `{}` contains non-Unicode characters. \\\n                ty only supports Unicode paths.\",\n                path.display()\n            )\n        })?\n    };\n\n    let project_path = args\n        .project\n        .as_ref()\n        .map(|project| {\n            if project.as_std_path().is_dir() {\n                Ok(SystemPath::absolute(project, &cwd))\n            } else {\n                Err(anyhow!(\n                    \"Provided project path `{project}` is not a directory\"\n                ))\n            }\n        })\n        .transpose()?\n        .unwrap_or_else(|| cwd.clone());\n\n    let check_paths: Vec<_> = args\n        .paths\n        .iter()\n        .map(|path| SystemPath::absolute(path, &cwd))\n        .collect();\n\n    let mode = if args.fix {\n        MainLoopMode::Fix(FixMode::ApplyFixes)\n    } else if args.add_ignore {\n        MainLoopMode::Fix(FixMode::AddIgnore)\n    } else {","sourceCodeStart":105,"sourceCodeEnd":141,"githubUrl":"https://github.com/astral-sh/ruff/blob/672bb4edf04c84f8b0753346359daee4057158f2/crates/ty/src/lib.rs#L105-L141","documentation":"`--project` selects the directory ty treats as the project root for configuration and metadata discovery, so ty validates `project.as_std_path().is_dir()` and fails fast otherwise. Any non-directory — a regular file, a broken symlink, or a nonexistent path — fails `is_dir()` and triggers this error. Common confusion: `--project` takes the directory that contains `pyproject.toml`, not the TOML file itself.","triggerScenarios":"`ty check --project ./pyproject.toml src/` (file passed instead of directory), `--project` pointing at a Python script you meant to type-check, a typo'd or nonexistent directory, or a CI job where the project dir is conditional and absent on some runners.","commonSituations":"Migrating from tools whose flag takes a config-file path; single-file projects where the `.py` file is passed to `--project` by mistake; monorepo pipelines computing `--project` from variables that can be empty.","solutions":["Point `--project` at the directory containing your `pyproject.toml` (usually just `.`)","To check a single file, pass it as a positional check path (`ty check script.py`) instead of `--project`","Verify before running: `test -d \"$PROJECT\" || echo \"--project must be an existing directory\"`"],"exampleFix":"# before\nty check --project ./pyproject.toml src/\n# after\nty check --project . src/","handlingStrategy":"validation","validationCode":"test -d \"$PROJECT_DIR\" || { echo \"--project must be an existing directory\" >&2; exit 2; }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Remember `--project` takes a directory, never a file; positional args are for files","Validate CI-computed `--project` values against the filesystem before invoking ty","Add a lint to scripts that flags `--project */pyproject.toml`-style usages"],"tags":["ty","cli","configuration","paths","validation"],"backgroundTag":null,"analyzedSha":"672bb4edf04c84f8b0753346359daee4057158f2","analyzedAt":"2026-08-16T08:54:05.464Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}