gitbutlerapp/gitbutler · error
project path not found
Error message
project path not found
What it means
AddProjectOutcome::PathNotFound mapped through try_project: add_project was called with a path that does not exist on disk. The path existence check runs before any git probing, so this is purely a filesystem precondition failure.
Source
Thrown at crates/gitbutler-project/src/project.rs:319
impl AddProjectOutcome {
/// This is for tests only.
///
/// Unwraps the `Project` if the project was actually added.
/// Panics if it was not.
pub fn unwrap_project(self) -> Project {
match self {
AddProjectOutcome::Added(p) => p,
_ => panic!("called `AddProjectOutcome::unwrap_project()` on a non-project outcome"),
}
}
/// Try to get the `Project`, returning an error if it was not added.
pub fn try_project(self) -> anyhow::Result<Project> {
match self {
AddProjectOutcome::Added(p) => Ok(p),
AddProjectOutcome::AlreadyExists(_) => Err(anyhow::anyhow!("project already exists")),
AddProjectOutcome::PathNotFound => Err(anyhow::anyhow!("project path not found")),
AddProjectOutcome::NotADirectory => {
Err(anyhow::anyhow!("project path is not a directory"))
}
AddProjectOutcome::BareRepository => {
Err(anyhow::anyhow!("bare repositories are not supported"))
}
AddProjectOutcome::NonMainWorktree => {
Err(anyhow::anyhow!("non-main worktrees are not supported"))
}
AddProjectOutcome::NoWorkdir => Err(anyhow::anyhow!("no workdir found for repository")),
AddProjectOutcome::NoDotGitDirectory => {
Err(anyhow::anyhow!("no .git directory found in repository"))
}
AddProjectOutcome::ReftableRefFormatUnsupported => Err(anyhow::anyhow!(
"unsupported repository reference format: reftable"
)),
AddProjectOutcome::NotAGitRepository(msg) => {
Err(anyhow::anyhow!("not a git repository: {msg}"))View on GitHub (pinned to caf1f223d3)
Solutions
- Check the path exists before calling add_project: std::path::Path::exists
- Normalize and canonicalize (std::fs::canonicalize) the path to eliminate relative-CWD and symlink surprises
- Fix the upstream step that was supposed to create/clone the directory, then retry
- In UI flows, use a native directory picker that only returns existing paths
Example fix
// before
let outcome = add_project(Path::new(&input), ...).try_project()?;
// after: validate before adding
let path = std::fs::canonicalize(&input)
.with_context(|| format!("path does not exist: {input}"))?;
let project = add_project(&path, ...).try_project()?; Defensive patterns
Strategy: validation
Validate before calling
let path = std::fs::canonicalize(&input)
.map_err(|_| anyhow!("path does not exist: {input}"))?;
let project = add_project(&path, ...).try_project()?; Type guard
fn existing_dir(p: impl AsRef<Path>) -> Option<std::path::PathBuf> {
std::fs::canonicalize(p).ok().filter(|p| p.is_dir())
} Try / catch
match add_project(Path::new(&input), ...) {
AddProjectOutcome::PathNotFound => {
// prompt the user with a directory picker instead of erroring out
pick_directory_and_retry()
}
outcome => outcome.try_project(),
} Prevention
- canonicalize user-supplied paths before use to catch typos, relative-CWD issues, and missing paths early
- Use native directory pickers that can only return existing folders
- In automation, assert the clone/checkout step succeeded before adding its output directory
When it happens
Trigger: add_project(path) where path was typo'd, relative and resolved against the wrong CWD, or deleted between user selection and the call; paths from stale config/sync on another machine; trailing whitespace or quotes in the path string.
Common situations: Paste-a-path flows in CLI/UI with typos; projects listed from another machine's settings; scripted setup referencing a checkout step that failed earlier so the directory was never created.
Related errors
- project path is not a directory
- no .git directory found in repository
- ProjectMissing
- project already exists
- bare repositories are not supported
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/f3498922c794bcec.
Report an issue: GitHub.