{"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":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but/src/command/legacy/setup.rs","lineNumber":257,"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":239,"sourceCodeEnd":275,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but/src/command/legacy/setup.rs#L239-L275","documentation":"Thrown when `AddProjectOutcome::NotADirectory` is returned during project registration in `but setup`. The path exists on disk but is a regular file, not a directory, so GitButler cannot treat it as a repository location.","triggerScenarios":"Calling the setup/add-project flow with a path that resolves to a file (e.g. a tracked file inside the repo, a tarball, or a symlink to a file) instead of a directory containing `.git`.","commonSituations":"Passing a file path by mistake (autocomplete picking a file); pointing at `myrepo.git` archive file; scripts interpolating wrong variables into the path.","solutions":["Check the target with `ls -la <path>`; confirm it is a directory.","Point setup at the repository root directory, not a file inside it.","If a symlink is involved, ensure it resolves to a directory."],"exampleFix":"// before\nbut setup ~/projects/myrepo/README.md\n// after\nbut setup ~/projects/myrepo","handlingStrategy":"validation","validationCode":"if (!fs.statSync(repoPath).isDirectory()) {\n  throw new Error(`${repoPath} is not a directory`);\n}","typeGuard":"function isDirectory(p: string): boolean {\n  try { return fs.statSync(p).isDirectory(); } catch { return false; }\n}","tryCatchPattern":"try {\n  await run(['but', 'setup', repoPath]);\n} catch (e) {\n  if (String(e).includes('is not a directory')) {\n    console.error('Pass the repository root directory, not a file.');\n  }\n  throw e;\n}","preventionTips":["Check `ls -la` output before running setup to confirm the target is a directory.","Avoid glob expansion in scripts that may select files.","Resolve symlinks with realpath before passing the path."],"tags":["filesystem","cli","not-a-directory","setup"],"backgroundTag":"path-is-not-a-directory","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}