{"record":{"id":"b16d2c9d7a438f5d","repo":"gitbutlerapp/gitbutler","slug":"configured-target-branch-has-no-push-remote","errorCode":null,"errorMessage":"Configured target branch has no push remote","messagePattern":"Configured target branch has no push remote","errorType":"validation","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/but-api/src/land/mod.rs","lineNumber":206,"sourceCode":"                );\n            }\n        }\n        crate::legacy::virtual_branches::get_base_branch_data(ctx, guard.write_permission())?\n            .ok_or_else(|| anyhow::anyhow!(\"No base branch configured\"))?\n    };\n\n    let target_branch_name = base_branch.short_name.clone();\n    if target_branch_name.is_empty() {\n        bail!(\"Configured target branch has no branch name\");\n    }\n    let fetch_remote_name = base_branch.remote_name.clone();\n    let push_remote_name = if base_branch.push_remote_name.is_empty() {\n        fetch_remote_name.clone()\n    } else {\n        base_branch.push_remote_name.clone()\n    };\n    if push_remote_name.is_empty() {\n        bail!(\"Configured target branch has no push remote\");\n    }\n\n    // Triangular remotes (fetch remote != push remote) are out of scope for now: the post-land\n    // reconcile reads the fetch remote's tracking ref, so a push to a different remote would not\n    // advance it and the reconcile would silently no-op. Refuse before mutating anything.\n    if push_remote_name != fetch_remote_name {\n        bail!(\n            \"`but merge` does not yet support triangular remotes (fetch `{fetch_remote_name}`, \\\n             push `{push_remote_name}`). Merge via a pull request instead, or configure a single \\\n             remote for the target branch.\"\n        );\n    }\n\n    let target_display = format!(\"{push_remote_name}/{target_branch_name}\");\n    let push_remote_url = if base_branch.push_remote_url.is_empty() {\n        &base_branch.remote_url\n    } else {\n        &base_branch.push_remote_url","sourceCodeStart":188,"sourceCodeEnd":224,"githubUrl":"https://github.com/gitbutlerapp/gitbutler/blob/58e5313667b857ef39a730e380af31816a7b1768/crates/but-api/src/land/mod.rs#L188-L224","documentation":"Landing pushes the merged result, so a push remote name is required. When the base-branch metadata has no push remote configured and the fetch remote also resolved to empty, `branch_land` bails because it cannot determine where to push the landed target branch.","triggerScenarios":"Calling `but merge` when `base_branch.push_remote_name` is empty and `remote_name` (used as fallback) is also empty — the workspace target lacks any remote configured.","commonSituations":"Repo with no `origin` remote (local-only repository); target branch set up against a purely local branch; remote removed after the target was configured.","solutions":["Add a remote (`git remote add origin <url>`) and re-configure the workspace target branch against it","Re-set the push target in GitButler so `push_remote_name` points at an existing remote","If the repo is intentionally local-only, land via plain git instead of `but merge`, which requires a remote target"],"exampleFix":"# before\nbut merge feature-branch\n# error: Configured target branch has no push remote\n\n# after\ngit remote add origin git@github.com:me/repo.git\nbut target set --remote origin --branch main\nbut merge feature-branch","handlingStrategy":"validation","validationCode":"let push_remote = if base_branch.push_remote_name.is_empty() { &base_branch.remote_name } else { &base_branch.push_remote_name };\nif push_remote.is_empty() {\n    println!(\"no remote configured; add one with `git remote add`\");\n    return Ok(());\n}","typeGuard":null,"tryCatchPattern":"match land_result {\n    Err(e) if e.to_string().contains(\"no push remote\") => {\n        add_remote_and_set_target();\n        retry_land();\n    }\n    other => other?,\n}","preventionTips":["Ensure the repo has at least one remote before initializing the GitButler workspace","Verify target configuration with `but target list`/status before landing","Don't remove remotes while a workspace target references them"],"tags":["gitbutler","config","remote","landing"],"backgroundTag":"missing-required-config-field","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"}