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

  1. Check the path exists before calling add_project: std::path::Path::exists
  2. Normalize and canonicalize (std::fs::canonicalize) the path to eliminate relative-CWD and symlink surprises
  3. Fix the upstream step that was supposed to create/clone the directory, then retry
  4. 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

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


AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20). Data as JSON: /api/errors/f3498922c794bcec. Report an issue: GitHub.