{"record":{"id":"014e54971f840af1","repo":"Hmbown/CodeWhale","slug":"refusing-to-push-onto-the-forge-default-branch-branch","errorCode":null,"errorMessage":"refusing to push onto the forge default branch {branch}","messagePattern":"refusing to push onto the forge default branch (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/dispatch_runner.rs","lineNumber":527,"sourceCode":"    )\n    .context(\"could not set the agent identity\")?;\n    git(Some(&repo), &[\"checkout\", \"--quiet\", \"-b\", &job.branch])\n        .context(\"could not create the cloud agent branch\")?;\n    git(\n        Some(&repo),\n        &[\"am\", \"--quiet\", \"--3way\", &patch_path.to_string_lossy()],\n    )\n    .context(\"the agent patch did not apply cleanly onto the target branch\")?;\n    git(Some(&repo), &[\"rev-parse\", \"HEAD\"]).map(|out| out.trim().to_string())\n}\n\n/// Push the prepared branch. Plain push only — `--force` is never passed, so\n/// an existing branch that is not a fast-forward fails closed instead of\n/// rewriting the target's history.\nfn push_branch(repo: &Path, remote_url: &str, branch: &str) -> Result<()> {\n    let remote_url = cloud_dispatch::validate_git_remote_url(remote_url)?;\n    if cloud_dispatch::is_forge_default_branch(branch) {\n        bail!(\"refusing to push onto the forge default branch {branch}\");\n    }\n    if looks_like_network_remote(&remote_url) && cloud_dispatch::classify_url(&remote_url).is_none()\n    {\n        bail!(\"refusing to push to a non-forge remote\");\n    }\n    if remote_branch_exists(&remote_url, branch)? {\n        bail!(\"refusing to update existing remote branch {branch}\");\n    }\n    git(\n        Some(repo),\n        &[\n            \"push\",\n            \"--quiet\",\n            \"--\",\n            &remote_url,\n            &format!(\"HEAD:refs/heads/{branch}\"),\n        ],\n    )","sourceCodeStart":509,"sourceCodeEnd":545,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/dispatch_runner.rs#L509-L545","documentation":"push_branch never force-pushes and additionally refuses to push to any branch the forge considers a default branch (e.g. main, master). This protects the repository's primary branch from being rewritten or polluted by dispatch jobs.","triggerScenarios":"push_branch is called (via open) with a branch name for which cloud_dispatch::is_forge_default_branch returns true, e.g. branch=\"main\".","commonSituations":"Configuring the dispatch job with an empty or wrongly-named branch that resolves to the default, running a job from inside a checkout whose working branch is main, or a template that fills the branch with the repo default.","solutions":["Use a distinct feature/agent branch name for the dispatch job (e.g. codewhale/<task>)","Fix the job config so the branch field is set explicitly to a non-default name","Verify the branch derivation logic in your tooling isn't falling back to HEAD's default branch"],"exampleFix":"// before\npush_branch(repo, remote_url, \"main\")\n// after\npush_branch(repo, remote_url, \"codewhale/fix-logging\")","handlingStrategy":"validation","validationCode":"if is_forge_default_branch(&branch) {\n    branch = format!(\"codewhale/{}\", task_slug); // pick a safe branch\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never pass the repo default branch as the dispatch branch","Prefix generated branch names with a distinctive slug","Sanitize user-provided branch names against defaults"],"tags":["git","push","safety"],"backgroundTag":"unsupported-operation","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}