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
- Convert the repository back to the files backend: `git refs migrate --ref-format=files` (git >= 2.45), then retry the command.
- Disable the global reftable default: `git config --global --unset init.defaultRefFormat` or set it to `files`.
- 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
- Keep `init.defaultRefFormat=files` (or unset) in global git config.
- Check ref format before pointing GitButler at a repo.
- Keep git and GitButler versions aligned with supported formats.
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
- The repository at uses the currently unsupported reftable…
- unsupported repository reference format: reftable
- Aborting due to empty branch name
- Ad-hoc (single-branch) branch moves are not supported…
- An octopus merge commits must have at least two parents
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)