{"record":{"id":"32b5b9cab5b2234a","repo":"gitbutlerapp/gitbutler","slug":"the-path-is-not-a-directory","errorCode":null,"errorMessage":"The path {} is not a directory","messagePattern":"The path (.+?) is not a directory","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but/src/command/legacy/setup.rs","lineNumber":238,"sourceCode":"                )?;\n            }\n            Ok(ProjectStatus::Added)\n        }\n        gitbutler_project::AddProjectOutcome::AlreadyExists(_) => {\n            if let Some(out) = out.for_human() {\n                writeln!(\n                    out,\n                    \"  {}\",\n                    t.success.paint(\"✓ Repository already in project registry\")\n                )?;\n            }\n            Ok(ProjectStatus::AlreadyExists)\n        }\n        gitbutler_project::AddProjectOutcome::PathNotFound => Err(anyhow::anyhow!(\n            \"The path {} does not exist\",\n            repo_path.display()\n        )),\n        gitbutler_project::AddProjectOutcome::NotADirectory => Err(anyhow::anyhow!(\n            \"The path {} is not a directory\",\n            repo_path.display()\n        )),\n        gitbutler_project::AddProjectOutcome::BareRepository => Err(anyhow::anyhow!(\n            \"The repository at {} is bare. GitButler requires a non-bare repository.\",\n            repo_path.display()\n        )),\n        gitbutler_project::AddProjectOutcome::NonMainWorktree => Err(anyhow::anyhow!(\n            \"The repository at {} is a non-main worktree. GitButler requires the main worktree.\",\n            repo_path.display()\n        )),\n        gitbutler_project::AddProjectOutcome::NoWorkdir => Err(anyhow::anyhow!(\n            \"The repository at {} has no working directory. GitButler requires a working directory.\",\n            repo_path.display()\n        )),\n        gitbutler_project::AddProjectOutcome::NoDotGitDirectory => Err(anyhow::anyhow!(\n            \"The repository at {} has no .git directory. GitButler requires a .git directory.\",\n            repo_path.display()","sourceCodeStart":220,"sourceCodeEnd":256,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but/src/command/legacy/setup.rs#L220-L256","documentation":"Raised while registering a repository during `but setup`: the path exists but is a regular file (or symlink to one), so `gitbutler_project` returned `AddProjectOutcome::NotADirectory`. GitButler project paths must be directories; nothing Git-related is attempted.","triggerScenarios":"Passing a file path where the project directory is expected, e.g. pointing at a script, a `.git` pack file, or a symlink that resolves to a file.","commonSituations":"Copy-pasting a file path from documentation instead of its parent folder; scripts appending a filename to a directory variable; symlinks that changed target type.","solutions":["Point at the directory that contains the repository, not at a file","Verify with `test -d /the/path && echo dir` before running","If the path is a symlink, check what it resolves to (`readlink -f /the/path`)"],"exampleFix":"# before: path is a file\nbut setup ~/repos/my-project/README.md\n\n# after: pass the directory\nbut setup ~/repos/my-project","handlingStrategy":"validation","validationCode":"let meta = std::fs::metadata(&repo_path)?;\nif !meta.is_dir() {\n    anyhow::bail!(\"{repo_path:?} is a file; pass the repository directory instead\");\n}","typeGuard":"fn is_not_a_directory(out: &gitbutler_project::AddProjectOutcome) -> bool {\n    matches!(out, gitbutler_project::AddProjectOutcome::NotADirectory)\n}","tryCatchPattern":"match add_project(&repo_path) {\n    Ok(out) if is_not_a_directory(&out) => { /* ask for the parent directory */ }\n    Ok(out) => { /* other outcomes */ }\n    Err(err) if err.to_string().contains(\"is not a directory\") => { /* directory guidance */ }\n    Err(err) => return Err(err),\n}","preventionTips":["Check `test -d` before passing paths to project registration","Never append filenames to directory variables used as arguments","Resolve symlinks (`readlink -f`) before validating directories"],"tags":["rust","cli","setup","path","filesystem"],"backgroundTag":"path-not-a-directory","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}