{"record":{"id":"3e9d64234ab7aeb2","repo":"jesseduffield/lazygit","slug":"branch-branchname-is-checked-out-by-worktree","errorCode":null,"errorMessage":"Branch {{.branchName}} is checked out by worktree {{.worktreeName}}","messagePattern":"Branch (.+?)\\} is checked out by worktree (.+?)\\}","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/gui/controllers/helpers/worktree_helper.go","lineNumber":84,"sourceCode":"\t})\n\n\treturn nil\n}\n\n// newWorktreeForPickerValue classifies the value the user picked or typed in the\n// worktrees-panel picker and routes to the matching creation flow:\n//   - an existing local branch -> a worktree that checks it out;\n//   - a remote branch -> a new local tracking branch + worktree;\n//   - anything else -> a new branch off the current ref + worktree.\n//\n// All three then feed the shared location menu. The picker filters out branches\n// already checked out somewhere, but a verbatim type-in is still guarded here.\nfunc (self *WorktreeHelper) newWorktreeForPickerValue(value string) error {\n\tif branch, ok := lo.Find(self.c.Model().Branches, func(branch *models.Branch) bool {\n\t\treturn branch.Name == value\n\t}); ok {\n\t\tif worktree, ok := git_commands.WorktreeForBranch(branch, self.c.Model().Worktrees); ok {\n\t\t\treturn errors.New(utils.ResolvePlaceholderString(self.c.Tr.BranchCheckedOutByWorktree,\n\t\t\t\tmap[string]string{\"branchName\": branch.Name, \"worktreeName\": worktree.Name}))\n\t\t}\n\n\t\tprompt := utils.ResolvePlaceholderString(self.c.Tr.WorktreeLocationPromptCheckout,\n\t\t\tmap[string]string{\"branchName\": branch.Name})\n\t\treturn self.promptForWorktreeLocation(branch.Name, prompt, func(path string) error {\n\t\t\treturn self.createWorktree(git_commands.NewWorktreeOpts{Path: path, Base: branch.RefName()}, context.WORKTREES_CONTEXT_KEY)\n\t\t})\n\t}\n\n\tif _, branchName, ok := self.refsHelper.ParseRemoteBranchName(value); ok {\n\t\tprompt := utils.ResolvePlaceholderString(self.c.Tr.WorktreeLocationPromptTrackingBranch,\n\t\t\tmap[string]string{\"name\": branchName, \"ref\": value})\n\t\treturn self.promptForWorktreeLocation(branchName, prompt, func(path string) error {\n\t\t\treturn self.createWorktree(git_commands.NewWorktreeOpts{Path: path, Base: value, Branch: branchName}, context.WORKTREES_CONTEXT_KEY)\n\t\t})\n\t}\n","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/jesseduffield/lazygit/blob/c477a2959b229fbf3284be0d4d2904ab61ec3c94/pkg/gui/controllers/helpers/worktree_helper.go#L66-L102","documentation":"Thrown by WorktreeHelper.newWorktreeForPickerValue when the user types a branch name (verbatim) that is already checked out by an existing worktree. Git refuses to check out the same branch in two worktrees, so lazygit blocks the operation up front. The branches-panel picker filters such branches out, but a free-form type-in bypasses that filter, hence this explicit guard.","triggerScenarios":"Calling the new-worktree flow with a value string that exactly matches a local branch for which git_commands.WorktreeForBranch(branch, model.Worktrees) returns a worktree. Typically: NewWorktree -> type a branch name that is already checked out in another worktree instead of picking from the filtered list.","commonSituations":"User forgets a branch is checked out in a long-lived worktree; stale worktree list after a worktree was removed outside lazygit; scripting the worktree creation flow with a hardcoded branch name.","solutions":["Switch to the existing worktree that already has the branch checked out (its name is in the error message) instead of creating a new one.","Create the new worktree from a different base or a new branch name rather than the checked-out branch.","If the existing worktree is stale, remove it first (worktrees panel), then retry.","As a developer embedding lazygit's helper, pre-filter candidate branch names against Model().Worktrees using git_commands.WorktreeForBranch before calling the flow."],"exampleFix":"// before\nvalue := \"feature-branch\" // already checked out in ../wt-feature\nerr := helper.newWorktreeForPickerValue(value)\n\n// after\nif wt, ok := git_commands.WorktreeForBranch(branch, model.Worktrees); ok {\n    return helper.Switch(wt, context.WORKTREES_CONTEXT_KEY)\n}\nerr := helper.newWorktreeForPickerValue(value)","handlingStrategy":"validation","validationCode":"func branchAvailableForWorktree(branch *models.Branch, worktrees []*models.Worktree) bool {\n    _, taken := git_commands.WorktreeForBranch(branch, worktrees)\n    return !taken\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Filter the branch picker against Model().Worktrees with git_commands.WorktreeForBranch before offering entries.","Show which worktree holds each branch in the UI so users self-select correctly.","When scripting worktree creation, verify the branch is not checked out anywhere first."],"tags":["git","worktree","branch","user-input"],"backgroundTag":null,"analyzedSha":"c477a2959b229fbf3284be0d4d2904ab61ec3c94","analyzedAt":"2026-08-15T08:34:32.451Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}