{"record":{"id":"47fe3bf28904eb48","repo":"Hmbown/CodeWhale","slug":"refusing-to-push-to-a-non-forge-remote","errorCode":null,"errorMessage":"refusing to push to a non-forge remote","messagePattern":"refusing to push to a non-forge remote","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/dispatch_runner.rs","lineNumber":531,"sourceCode":"    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    )\n    .map(|_| ())\n    .context(\n        \"could not push the cloud agent branch (it may need credentials or the branch may have moved)\",\n    )","sourceCodeStart":513,"sourceCodeEnd":549,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/dispatch_runner.rs#L513-L549","documentation":"push_branch validates the remote URL twice: it must be a syntactically valid git remote, and if it looks like a network remote (http(s)/ssh) it must classify as a known forge (GitHub/GitLab etc.). Pushing dispatch output to a non-forge network remote is refused.","triggerScenarios":"push_branch receives a remote_url that looks like a network URL (https://git.example.com/...) but cloud_dispatch::classify_url cannot recognize it as a supported forge.","commonSituations":"Self-hosted or niche forges not in the classifier, push mirrors, generic git servers, or a mistyped URL whose host isn't a recognized forge domain.","solutions":["Point the remote at a supported forge (github.com/gitlab.com etc.)","Add the repository as a recognized forge if your version supports custom forge hosts","Use an SSH/URL form the classifier accepts, or verify the URL spelling"],"exampleFix":"// before\npush_branch(repo, \"https://git.mycompany.internal/team/repo.git\", branch)\n// after\npush_branch(repo, \"https://github.com/team/repo.git\", branch)","handlingStrategy":"validation","validationCode":"if classify_url(&remote_url).is_none() {\n    // remote is not a supported forge; reconfigure the remote\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use remotes hosted on supported forges for dispatch jobs","Double-check remote URL spelling and scheme","Keep self-hosted forges out of dispatch workflows unless supported"],"tags":["git","remote","forge","url"],"backgroundTag":"invalid-url-format","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"}