gitbutlerapp/gitbutler · error

The repository at is a non-main worktree. GitButler…

Error message

The repository at {} is a non-main worktree. GitButler requires the main worktree.

What it means

Worktree-kind validation during project setup (repo command): the path points at a linked (non-main) worktree of a repository, but GitButler only manages the main worktree. Run setup from the repository's main worktree directory instead.

Solutions

  1. Run setup from the main worktree (the original clone directory).
  2. If you need GitButler on this code, clone the repository fresh at this path.
  3. Inspect `git worktree list` to identify the main worktree path.

Example fix

// before
cd ~/repo-feature-branch-worktree && but setup
// after
cd ~/repo && but setup
Defensive patterns

Strategy: validation

Validate before calling

const main = await run(['git', '-C', repoPath, 'rev-parse', '--path-format=absolute', '--git-common-dir']);
const toplevel = await run(['git', '-C', repoPath, 'rev-parse', '--show-toplevel']);
// linked worktrees have a git-common-dir outside <toplevel>/.git

Type guard

function isMainWorktree(p: string): boolean {
  const r = cp.spawnSync('git', ['-C', p, 'rev-parse', '--git-dir']);
  return r.status === 0 && r.stdout.toString().trim() === '.git';
}

Try / catch

try {
  await run(['but', 'setup', repoPath]);
} catch (e) {
  if (String(e).includes('non-main worktree')) {
    console.error('Run but setup from the main worktree (see: git worktree list).');
  }
  throw e;
}

Prevention

When it happens

Trigger: Running `but setup` inside a linked worktree created with `git worktree add <path>` instead of the original clone directory.

Common situations: Developers using `git worktree` for parallel branches pointing GitButler at the secondary worktree; automation that checks out worktrees into temp dirs.

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/267adecb48e258d7. Report an issue: GitHub.

Appendix: source

Thrown at crates/but/src/command/legacy/setup.rs:265

                    "  {}",
                    t.success.paint("✓ Repository already in project registry")
                )?;
            }
            Ok(ProjectStatus::AlreadyExists)
        }
        gitbutler_project::AddProjectOutcome::PathNotFound => Err(anyhow::anyhow!(
            "The path {} does not exist",
            repo_path.display()
        )),
        gitbutler_project::AddProjectOutcome::NotADirectory => Err(anyhow::anyhow!(
            "The path {} is not a directory",
            repo_path.display()
        )),
        gitbutler_project::AddProjectOutcome::BareRepository => Err(anyhow::anyhow!(
            "The repository at {} is bare. GitButler requires a non-bare repository.",
            repo_path.display()
        )),
        gitbutler_project::AddProjectOutcome::NonMainWorktree => Err(anyhow::anyhow!(
            "The repository at {} is a non-main worktree. GitButler requires the main worktree.",
            repo_path.display()
        )),
        gitbutler_project::AddProjectOutcome::NoWorkdir => Err(anyhow::anyhow!(
            "The repository at {} has no working directory. GitButler requires a working directory.",
            repo_path.display()
        )),
        gitbutler_project::AddProjectOutcome::NoDotGitDirectory => Err(anyhow::anyhow!(
            "The repository at {} has no .git directory. GitButler requires a .git directory.",
            repo_path.display()
        )),
        gitbutler_project::AddProjectOutcome::ReftableRefFormatUnsupported => Err(anyhow::anyhow!(
            "The repository at {} uses the currently unsupported reftable reference format.",
            repo_path.display()
        )),
        gitbutler_project::AddProjectOutcome::NotAGitRepository(_) => Err(anyhow::anyhow!(
            "The path {} is not a git repository.",
            repo_path.display()

View on GitHub (pinned to 58e5313667)