gitbutlerapp/gitbutler · error

Could not open projects file at '{}'. It was moved to {}. Re

Error message

Could not open projects file at '{}'.
It was moved to {}.
Reopen or refresh the app to start fresh.
Error was: {probably_file_load_err}

What it means

At startup the project controller tries to load the projects file; when loading fails, it renames the broken file to a backup path and bails with this message. The next launch starts fresh (projects must be re-added), and only when `max_attempts` backup files already exist does it give up entirely. The original parse error is included as `probably_file_load_err`.

Source

Thrown at crates/gitbutler-project/src/controller.rs:150

                let projects_path = self.local_data_dir.join("projects.json");
                let max_attempts = 255;
                for round in 1..max_attempts {
                    let backup_path = self
                        .local_data_dir
                        .join(format!("projects.json.maybe-broken-{round:02}"));
                    if backup_path.is_file() {
                        continue;
                    }

                    if let Err(err) = std::fs::rename(&projects_path, &backup_path) {
                        tracing::error!(
                            "Failed to rename {} to {} - application may fail to startup: {err}",
                            projects_path.display(),
                            backup_path.display()
                        );
                    }

                    bail!(
                        "Could not open projects file at '{}'.\nIt was moved to {}.\nReopen or refresh the app to start fresh.\nError was: {probably_file_load_err}",
                        projects_path.display(),
                        backup_path.display()
                    );
                }
                bail!("There were already {max_attempts} backup project files - giving up")
            }
        }
    }
}

impl Controller {
    pub(crate) fn from_path(path: impl Into<PathBuf>) -> Self {
        let path = path.into();
        Self {
            projects_storage: storage::Storage::from_path(&path),
            local_data_dir: path,
        }

View on GitHub (pinned to caf1f223d3)

Solutions

  1. Restart/refresh the app: the broken file was already moved aside and a fresh one is created — re-add your projects
  2. If you need the old list, open the renamed backup file next to the original path and salvage entries manually
  3. If restore reports the backup limit was hit, delete old backup files so a new one can be created
  4. Fix the root cause (sync conflicts, unclean shutdowns, disk space) before re-adding projects
Defensive patterns

Strategy: fallback

Validate before calling

// validate the projects file before the controller loads it
let raw = std::fs::read_to_string(&projects_path)?;
serde_json::from_str::<Vec<Project>>(&raw)
    .with_context(|| format!("projects file at {} is corrupt", projects_path.display()))?;

Try / catch

match Controller::load_all(&paths) {
    Err(err) if err.to_string().contains("Could not open projects file") => {
        // app already quarantined the file; start fresh, optionally salvage from the backup
    }
    other => other,
}

Prevention

When it happens

Trigger: Loading a projects file that fails to parse — invalid content from a partial write, a crash during save, or external truncation — while fewer than `max_attempts` backups exist.

Common situations: Power loss or forced quit during project save; disk-full during write; cloud-sync tools (Dropbox & co) corrupting the config; hand edits to the projects file.

Related errors


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