gitbutlerapp/gitbutler · error
The path is not a directory
Error message
The path {} is not a directory What it means
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.
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.
Example fix
// before but setup ~/projects/myrepo/README.md // after but setup ~/projects/myrepo
Defensive patterns
Strategy: validation
Validate before calling
if (!fs.statSync(repoPath).isDirectory()) {
throw new Error(`${repoPath} is not a directory`);
} Type guard
function isDirectory(p: string): boolean {
try { return fs.statSync(p).isDirectory(); } catch { return false; }
} Try / catch
try {
await run(['but', 'setup', repoPath]);
} catch (e) {
if (String(e).includes('is not a directory')) {
console.error('Pass the repository root directory, not a file.');
}
throw e;
} Prevention
- 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.
When it happens
Trigger: 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`.
Common situations: Passing a file path by mistake (autocomplete picking a file); pointing at `myrepo.git` archive file; scripts interpolating wrong variables into the path.
Related errors
- The path does not exist
- The repository at has no .git directory. GitButler requires…
- `but setup` cannot run from a linked worktree; run it from…
- Can only open the GUI on directories
- Installation path is a file, not a directory. Please…
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/32b5b9cab5b2234a.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but/src/command/legacy/setup.rs:257
)?;
}
Ok(ProjectStatus::Added)
}
gitbutler_project::AddProjectOutcome::AlreadyExists(_) => {
if let Some(out) = out.for_human() {
writeln!(
out,
" {}",
t.success.paint("✓ Repository already in project registry")
)?;
}
Ok(ProjectStatus::AlreadyExists)
}
gitbutler_project::AddProjectOutcome::PathNotFound => Err(anyhow::anyhow!(
"The path {} does not exist",
repo_path.display()
)),
gitbutler_project::AddProjectOutcome::NotADirectory => Err(anyhow::anyhow!(
"The path {} is not a directory",
repo_path.display()
)),
gitbutler_project::AddProjectOutcome::BareRepository => Err(anyhow::anyhow!(
"The repository at {} is bare. GitButler requires a non-bare repository.",
repo_path.display()
)),
gitbutler_project::AddProjectOutcome::NonMainWorktree => Err(anyhow::anyhow!(
"The repository at {} is a non-main worktree. GitButler requires the main worktree.",
repo_path.display()
)),
gitbutler_project::AddProjectOutcome::NoWorkdir => Err(anyhow::anyhow!(
"The repository at {} has no working directory. GitButler requires a working directory.",
repo_path.display()
)),
gitbutler_project::AddProjectOutcome::NoDotGitDirectory => Err(anyhow::anyhow!(
"The repository at {} has no .git directory. GitButler requires a .git directory.",
repo_path.display()View on GitHub (pinned to 58e5313667)