{"record":{"id":"267adecb48e258d7","repo":"gitbutlerapp/gitbutler","slug":"the-repository-at-is-a-non-main-worktree-gitbu","errorCode":null,"errorMessage":"The repository at {} is a non-main worktree. GitButler requires the main worktree.","messagePattern":"The repository at (.+?) is a non-main worktree\\. GitButler requires the main worktree\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but/src/command/legacy/setup.rs","lineNumber":246,"sourceCode":"                    \"  {}\",\n                    t.success.paint(\"✓ Repository already in project registry\")\n                )?;\n            }\n            Ok(ProjectStatus::AlreadyExists)\n        }\n        gitbutler_project::AddProjectOutcome::PathNotFound => Err(anyhow::anyhow!(\n            \"The path {} does not exist\",\n            repo_path.display()\n        )),\n        gitbutler_project::AddProjectOutcome::NotADirectory => Err(anyhow::anyhow!(\n            \"The path {} is not a directory\",\n            repo_path.display()\n        )),\n        gitbutler_project::AddProjectOutcome::BareRepository => Err(anyhow::anyhow!(\n            \"The repository at {} is bare. GitButler requires a non-bare repository.\",\n            repo_path.display()\n        )),\n        gitbutler_project::AddProjectOutcome::NonMainWorktree => Err(anyhow::anyhow!(\n            \"The repository at {} is a non-main worktree. GitButler requires the main worktree.\",\n            repo_path.display()\n        )),\n        gitbutler_project::AddProjectOutcome::NoWorkdir => Err(anyhow::anyhow!(\n            \"The repository at {} has no working directory. GitButler requires a working directory.\",\n            repo_path.display()\n        )),\n        gitbutler_project::AddProjectOutcome::NoDotGitDirectory => Err(anyhow::anyhow!(\n            \"The repository at {} has no .git directory. GitButler requires a .git directory.\",\n            repo_path.display()\n        )),\n        gitbutler_project::AddProjectOutcome::ReftableRefFormatUnsupported => Err(anyhow::anyhow!(\n            \"The repository at {} uses the currently unsupported reftable reference format.\",\n            repo_path.display()\n        )),\n        gitbutler_project::AddProjectOutcome::NotAGitRepository(_) => Err(anyhow::anyhow!(\n            \"The path {} is not a git repository.\",\n            repo_path.display()","sourceCodeStart":228,"sourceCodeEnd":264,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/caf1f223d3cfb94488c9198ad34487c6006c648f/crates/but/src/command/legacy/setup.rs#L228-L264","documentation":"Raised while registering a repository: the path is a git worktree, but a linked (non-main) one — `AddProjectOutcome::NonMainWorktree`. These are created with `git worktree add` and share the object database with the main worktree; GitButler only supports operating on the main worktree.","triggerScenarios":"Running setup inside a directory created by `git worktree add ../hotfix` (its `.git` is a file pointing back at the main repo's worktrees area), rather than in the original clone.","commonSituations":"Developers using linked worktrees for parallel branches; CI agents reusing a worktree checkout; opening a worktree directory from a recent-files list.","solutions":["Run setup in the main worktree of the clone (where the real `.git` directory lives)","Find the main worktree from the linked one: `git -C /the/path rev-parse --git-common-dir` strips the trailing path — or check `git worktree list`","If you need isolation, clone the repository again instead of using a linked worktree"],"exampleFix":"# before: linked worktree created by 'git worktree add'\nbut setup ~/hotfix-worktree\n\n# after: main worktree of the same clone\ngit -C ~/hotfix-worktree worktree list   # locate the main checkout\nbut setup ~/repos/project               # the main worktree","handlingStrategy":"validation","validationCode":"let output = std::process::Command::new(\"git\")\n    .args([\"-C\", repo_path.to_str().unwrap(), \"rev-parse\", \"--git-path\", \"..\"])\n    .output()?;\n// simpler: compare git-dir and git-common-dir\nlet git_dir = std::process::Command::new(\"git\").args([\"-C\", path, \"rev-parse\", \"--git-dir\"]).output()?;\nlet common_dir = std::process::Command::new(\"git\").args([\"-C\", path, \"rev-parse\", \"--git-common-dir\"]).output()?;\nif git_dir.stdout != common_dir.stdout {\n    anyhow::bail!(\"linked worktree; register the main worktree instead\");\n}","typeGuard":"fn is_non_main_worktree(out: &gitbutler_project::AddProjectOutcome) -> bool {\n    matches!(out, gitbutler_project::AddProjectOutcome::NonMainWorktree)\n}","tryCatchPattern":"match add_project(&repo_path) {\n    Ok(out) if is_non_main_worktree(&out) => { /* locate main worktree via 'git worktree list' */ }\n    Ok(out) => { /* other outcomes */ }\n    Err(err) if err.to_string().contains(\"non-main worktree\") => { /* worktree guidance */ }\n    Err(err) => return Err(err),\n}","preventionTips":["Detect linked worktrees early: `.git` being a file (not a directory) is the tell","Use `git worktree list` to find the main checkout before registering projects","Prefer a separate clone over `git worktree add` when a tool will manage the repo"],"tags":["rust","cli","setup","git","worktree"],"backgroundTag":"git-linked-worktree-unsupported","analyzedSha":"caf1f223d3cfb94488c9198ad34487c6006c648f","analyzedAt":"2026-08-20T07:55:40.983Z","schemaVersion":2},"datasetVersion":"2026-08-31T22:30:34.772Z"}