{"record":{"id":"91150bededb1162b","repo":"gitbutlerapp/gitbutler","slug":"but-merge-requires-an-active-gitbutler-workspace-gitbutler-91150b","errorCode":null,"errorMessage":"`but merge` requires an active GitButler workspace (`gitbutler/workspace`). Switch into the workspace and try again.","messagePattern":"`but merge` requires an active GitButler workspace \\(`gitbutler/workspace`\\)\\. Switch into the workspace and try again\\.","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but/src/command/legacy/merge/mod.rs","lineNumber":35,"sourceCode":"\npub fn handle(\n    ctx: &mut Context,\n    out: &mut OutputChannel,\n    branch_id: &str,\n    yes: bool,\n    no_ff: bool,\n    whole_stack: bool,\n) -> anyhow::Result<()> {\n    // Resolve the branch identifier and read the target configuration. The managed-workspace guard\n    // runs here for a friendly message before the prompt; the API enforces it again, along with the\n    // bottom-segment, conflicted-commit, and triangular-remote guards, before mutating anything.\n    let (branch_name, base_branch) = {\n        let mut guard = ctx.exclusive_worktree_access();\n\n        {\n            let (_repo, ws, _db) = ctx.workspace_and_db_with_perm(guard.read_permission())?;\n            if !ws.kind.has_managed_ref() {\n                bail!(\n                    \"`but merge` requires an active GitButler workspace (`gitbutler/workspace`). \\\n                     Switch into the workspace and try again.\"\n                );\n            }\n        }\n\n        let id_map = IdMap::new_from_context(ctx, guard.read_permission())?;\n        let resolved_ids = id_map.parse_using_context(branch_id, ctx)?;\n        if resolved_ids.is_empty() {\n            bail!(\"Could not find branch: {branch_id}\");\n        }\n        if resolved_ids.len() > 1 {\n            bail!(\"Ambiguous branch '{branch_id}', matches multiple items\");\n        }\n\n        let branch_name = match &resolved_ids[0] {\n            CliId::Branch(branch) => branch.name.clone(),\n            other => bail!(\"Expected a branch ID, got {}\", other.kind_for_humans()),","sourceCodeStart":17,"sourceCodeEnd":53,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but/src/command/legacy/merge/mod.rs#L17-L53","documentation":"The `but merge` command only works inside an active GitButler workspace: the repository must have the managed `gitbutler/workspace` ref, and the loaded workspace kind must report `has_managed_ref()`. The CLI checks this up front (the API enforces it again before mutating anything) and bails with this message when the workspace is absent or unmanaged, because landing a branch onto a target is only defined for GitButler-managed workspaces.","triggerScenarios":"Running `but merge <branch-id>` in a plain Git repository with no `gitbutler/workspace` ref, or in a repository where the workspace exists but its `kind` does not have a managed ref (e.g. after workspace teardown, or while in a detached/unmanaged state). The check runs at the top of `handle` after acquiring exclusive worktree access via `ctx.workspace_and_db_with_perm`.","commonSituations":"Developer runs `but merge` in a repo that has never had `but init`/workspace creation. The workspace was just removed (e.g. after landing the last branch or `but workspace goto` onto a plain branch). The command is executed with `-C <path>` pointing at a non-workspace sub-repo or wrong directory.","solutions":["Initialize or re-enter a GitButler workspace first (e.g. `but init` or `but` to enter the TUI and create a workspace), then run `but merge` again.","Check `git rev-parse gitbutler/workspace` in the repo to confirm the managed ref exists; if missing, the workspace is not active.","Confirm the working directory: run the command inside the GitButler-managed repository root, not a nested/plain checkout.","If the workspace was expected to exist, inspect workspace state with `but workspace` / `but status` and re-create it if it was torn down."],"exampleFix":"// before: fails in a plain git repo\nbut merge branch-abc\n// error: `but merge` requires an active GitButler workspace\n// after: ensure workspace exists first\nbut init\nbut merge branch-abc","handlingStrategy":"validation","validationCode":"// Check for the managed workspace ref before invoking but merge:\nconst refExists = runGit(['rev-parse', '--verify', 'gitbutler/workspace']).success;\nif (!refExists) {\n  throw new Error('Not in a GitButler workspace; run but init first.');\n}","typeGuard":null,"tryCatchPattern":"try {\n  runBut(['merge', branchId]);\n} catch (e) {\n  if (e.stderr.includes('requires an active GitButler workspace')) {\n    runBut(['init']); // create/enter workspace, then retry once\n    runBut(['merge', branchId]);\n  } else {\n    throw e;\n  }\n}","preventionTips":["Always run but merge from inside a GitButler-managed repository root.","Initialize the workspace (but init / entering the TUI) before landing commands.","After workspace teardown (last branch landed, workspace goto), re-create it before further but merge calls.","Check `git rev-parse gitbutler/workspace` in CI before invoking landing commands."],"tags":["cli","gitbutler","workspace","prerequisite-missing"],"backgroundTag":"workspace-not-initialized","analyzedSha":"58e5313667b857ef39a730e380af31816a7b1768","analyzedAt":"2026-09-18T06:50:32.052Z","contentChangedAt":"2026-09-18T06:50:32.052Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}