gitbutlerapp/gitbutler · error
ProjectMissing
ProjectMissing
Error message
Could not open repository at '{}'{suffix} What it means
ProjectController::get_inner with validate=true opens an isolated repo at project.worktree_dir; if open_isolated_repo fails, the error 'Could not open repository at ...' is returned with Code::ProjectMissing. The suffix ' as it does not exist' is appended when the worktree directory is missing entirely, distinguishing a vanished path from an unopenable (present but broken) repository.
Source
Thrown at crates/gitbutler-project/src/controller.rs:299
/// Like [`Self::get()`], but will assure the project still exists and is valid by
/// opening a git repository. This should only be done for critical points in time.
pub(crate) fn get_validated(&self, id: ProjectHandleOrLegacyProjectId) -> Result<Project> {
self.get_inner(id, true)
}
fn get_inner(&self, id: ProjectHandleOrLegacyProjectId, validate: bool) -> Result<Project> {
let mut project = self.projects_storage.get(id)?;
// BACKWARD-COMPATIBLE MIGRATION
project.migrate()?;
if validate {
let repo = project.open_isolated_repo();
if repo.is_err() {
let suffix = if !project.worktree_dir.exists() {
" as it does not exist"
} else {
""
};
return Err(anyhow!(
"Could not open repository at '{}'{suffix}",
project.worktree_dir.display()
)
.context(Code::ProjectMissing));
}
}
match project.gb_dir() {
Ok(gb_dir) => {
if !gb_dir.exists()
&& let Err(error) = std::fs::create_dir_all(&gb_dir)
{
tracing::error!(project_id = %project.id, ?error, "failed to create \"{}\" on project get", gb_dir.display());
}
}
Err(error) => {
tracing::error!(project_id = %project.id, ?error, "failed to resolve storage directory on project get");
}View on GitHub (pinned to caf1f223d3)
Solutions
- Confirm the path still exists and contains a valid .git; if it moved, re-add the project at the new location and remove the stale entry
- Reconnect the drive/mount that hosts the worktree, then retry
- On startup, drop project records whose worktree_dir no longer exists so users re-onboard cleanly instead of hitting ProjectMissing mid-session
- If the directory exists but still fails, inspect .git integrity (git fsck) — a present-but-broken repo produces the suffix-less variant
Example fix
// before
let project = controller.get_inner(id_or_handle, /* validate */ true)?;
// after: pre-validate stored projects and evict stale ones
let project = controller.get_inner(id_or_handle, false)?;
if !project.worktree_dir.is_dir() {
controller.delete_project(project.id)?;
anyhow::bail!("project path {} is gone — re-add the project", project.worktree_dir.display());
}
let project = controller.get_inner(id_or_handle, true)?; Defensive patterns
Strategy: validation
Validate before calling
// validate the stored path before a validating get
let stored = controller.get_inner(id_or_handle.clone(), /* validate */ false)?;
if !stored.worktree_dir.exists() {
anyhow::bail!(
"project path {} no longer exists — remove the project and re-add it",
stored.worktree_dir.display()
);
}
let project = controller.get_inner(id_or_handle, true)?; Type guard
fn project_is_on_disk(project: &Project) -> bool {
project.worktree_dir.is_dir()
} Try / catch
match controller.get_inner(id, true) {
Ok(project) => Ok(project),
Err(err) if err.to_string().contains("Could not open repository") => {
// Code::ProjectMissing: drive unmounted / folder moved — prompt re-add
prompt_user_to_re_add_project()
}
Err(err) => Err(err),
} Prevention
- Validate project paths at startup and offer re-onboarding for missing directories
- Detect moved repositories (search nearby paths for the same repo id) before failing
- For removable-media projects, check mount state before opening and surface a 'drive not connected' state instead of an error
When it happens
Trigger: The project folder was moved, renamed, or deleted after being added; an external/unmounted drive holding the worktree; a corrupted .git making even isolated open fail; a stale project row in the app database pointing at a path from another machine.
Common situations: Users moving repositories in Finder/Explorer after onboarding; projects on network mounts or removable media that are disconnected at startup; synced settings carrying project records to a machine where the path does not exist; .git dir permissions broken.
Related errors
- project path not found
- project path is not a directory
- no .git directory found in repository
- When using OpenAI in a bring your own key configuration, you
- Could not open projects file at '{}'. It was moved to {}. Re
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/6e727a50e86f1fde.
Report an issue: GitHub.