gitbutlerapp/gitbutler · error

The repository at uses the currently unsupported reftable…

Error message

The repository at {} uses the currently unsupported reftable reference format.

What it means

GitButler only supports the traditional loose/packed ref storage. When adding a project whose repository uses the newer `reftable` reference format, project add fails with this error because the required ref operations are not implemented for reftable.

Solutions

  1. Convert the repository back to the files backend: `git refs migrate --ref-format=files` (git >= 2.45), then retry the command.
  2. Disable the global reftable default: `git config --global --unset init.defaultRefFormat` or set it to `files`.
  3. If conversion is not possible, clone the repository into a new repo that uses the files ref format and add that instead.

Example fix

// before (in the target repo)
$ git config extensions.refstorage reftable
// after
$ cd /path/to/repo
git refs migrate --ref-format=files
rm .git/config # or: git config --unset extensions.refstorage
Defensive patterns

Strategy: validation

Validate before calling

const fmt = fs.readFileSync('.git/refs/.extensions.refstorage', 'utf8').trim();
// or: git rev-parse --show-ref-format
if (fmt === 'reftable') throw new Error('convert repo: git refs migrate --ref-format=files');

Try / catch

try {
  addProject(dir);
} catch (e) {
  if (String(e).includes('reftable')) {
    console.error('Repo uses reftable; run `git refs migrate --ref-format=files` first');
  }
  throw e;
}

Prevention

When it happens

Trigger: Running `but` (dispatch_subcommand) on a repository whose .git uses reftable; gitbutler_project::add_project returns AddProjectOutcome::ReftableRefFormatUnsupported and the CLI converts it into this anyhow error.

Common situations: Repository was cloned or created with a recent git version configured with `git config --global init.defaultRefFormat reftable` or `refs.format reftable`; repos created by tools defaulting to reftable.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18). Data as JSON: /api/errors/313d96dae1798cbe. Report an issue: GitHub.

Appendix: source

Thrown at crates/but/src/lib.rs:813

            .map(|()| DispatchOutcome::Return);
        }
        Subcommands::Edit { file } => {
            let path = args.current_dir.join(&file);
            return Ok(DispatchOutcome::ExitWithoutDestructors(
                tui::editor::edit_file(&path),
            ));
        }
        #[cfg(feature = "legacy")]
        Subcommands::Setup { init } => {
            let repo = match but_api::legacy::projects::add_project_best_effort(
                args.current_dir.clone(),
            )? {
                gitbutler_project::AddProjectOutcome::Added(project)
                | gitbutler_project::AddProjectOutcome::AlreadyExists(project) => {
                    gix::open(project.git_dir())?
                }
                gitbutler_project::AddProjectOutcome::ReftableRefFormatUnsupported => {
                    return Err(anyhow::anyhow!(
                            "The repository at {} uses the currently unsupported reftable reference format.",
                            args.current_dir.display()
                        )
                        .into());
                }
                _ => command::legacy::setup::find_or_initialize_repo(&args.current_dir, out, init)?,
            };
            let mut ctx = but_ctx::Context::from_repo_with_settings(repo, app_settings.clone())?;
            let mut guard = ctx.exclusive_worktree_access();
            return command::legacy::setup::repo(
                &mut ctx,
                &args.current_dir,
                out,
                guard.write_permission(),
            )
            .context("Failed to set up GitButler project.")
            .map(|()| DispatchOutcome::Return)
            .map_err(CliError::from);

View on GitHub (pinned to 58e5313667)