affaan-m/ECC · error
git rebase failed: {}{}
Error message
git rebase failed: {}{} What it means
Thrown by rebase_onto_base at ecc2/src/worktree/mod.rs:950 when `git -C <worktree.path> rebase <base_branch>` exits non-zero. On failure the code first attempts `git -C <worktree.path> rebase --abort` to leave the worktree in a clean state, captures any abort warning, formats stdout+stderr from the failed rebase, and bails with both pieces. Unlike the merge path, this error always tries to clean up the in-progress rebase before propagating.
Source
Thrown at ecc2/src/worktree/mod.rs:950
.arg("-C")
.arg(&worktree.path)
.args(["rebase", "--abort"])
.output()
.context("Failed to abort unsuccessful rebase")?;
let abort_warning = if abort_output.status.success() {
String::new()
} else {
format!(
" (rebase abort warning: {})",
String::from_utf8_lossy(&abort_output.stderr).trim()
)
};
let stderr = format!(
"{}\n{}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)
);
anyhow::bail!("git rebase failed: {}{}", stderr.trim(), abort_warning);
}
let after_head = branch_head_oid_in_repo(&repo_root, &worktree.branch)?;
let rebase_output = format!(
"{}\n{}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)
);
Ok(RebaseOutcome {
branch: worktree.branch.clone(),
base_branch: worktree.base_branch.clone(),
already_up_to_date: before_head == after_head || rebase_output.contains("up to date"),
})
}
pub fn branch_head_oid(worktree: &WorktreeInfo, branch: &str) -> Result<String> {
let repo_root = base_checkout_path(worktree)?;View on GitHub (pinned to 01e15490f0)
Solutions
- Read the formatted stderr in the error message to find conflict paths; if the auto-abort succeeded the worktree is clean — resolve conflicts in a manual rebase (`git -C <worktree_path> rebase <base_branch>`), or pick a different strategy (merge instead).
- If the abort also failed (the trailing `(rebase abort warning: ...)` is non-empty), run `git -C <worktree_path> rebase --abort` manually until HEAD stabilizes, then investigate.
- Refresh the worktree's view of base_branch first: `git -C <worktree_path> fetch origin <base_branch>` so the rebase target is current.
- Fall back to merge_into_base if conflicts are too entangled to rebase cleanly.
Example fix
// before
let outcome = rebase_onto_base(&worktree)?;
// after: fall back to merge when rebase conflicts
let outcome = match rebase_onto_base(&worktree) {
Ok(o) => o,
Err(e) => {
tracing::warn!("rebase failed, falling back to merge: {e}");
// rebase_onto_base already aborted the in-progress rebase
merge_into_base(&worktree).map(|m| RebaseOutcome {
branch: m.branch,
base_branch: m.base_branch,
already_up_to_date: m.already_up_to_date,
})?
}
}; Defensive patterns
Strategy: try-catch
Validate before calling
// Ensure base_branch is current and the worktree can see it
Command::new("git").arg("-C").arg(&worktree.path)
.args(["fetch", "origin", &worktree.base_branch]).status()?;
if has_uncommitted_changes(&worktree)? {
anyhow::bail!("worktree dirty; cannot safely rebase");
} Type guard
null
Try / catch
match rebase_onto_base(&worktree) {
Ok(o) => Ok(o),
Err(e) if e.to_string().starts_with("git rebase failed") => {
// rebase_onto_base already attempted --abort; fall back to a merge
tracing::warn!("rebase failed, falling back to merge: {e}");
merge_into_base(&worktree).map(|m| RebaseOutcome {
branch: m.branch, base_branch: m.base_branch,
already_up_to_date: m.already_up_to_date,
})
}
Err(e) => Err(e),
} Prevention
- Fetch base_branch right before rebasing so the target is fresh.
- Prefer merge over rebase for long-lived branches to avoid deep conflict replays.
- Surface the abort-warning suffix to the user so they know whether the worktree is clean.
- Record pre-rebase HEAD so you can detect the rare case where abort itself moved HEAD.
When it happens
Trigger: Content conflicts between the worktree branch and base_branch during replay; the base branch ref no longer exists or was force-pushed; a rebase hook (post-checkout, pre-rebase) rejected a step; binary/LFS conflicts; the worktree path is locked by another git process.
Common situations: Base branch advanced with conflicting changes since the worktree branched off; rebase of a long-lived feature branch with many squashed commits; pre-rebase hook (e.g. branch-protection) returns non-zero; LFS object missing on the base side.
Related errors
- Merge blocked between {left_branch} and {right_branch} by {}
- git merge failed: {stderr}
- Worktree {} has uncommitted changes; commit or discard them
- git apply failed while trying to {action}: {stderr}
- git worktree list --porcelain failed: {stderr}
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/cfb2127db11b4bc5.
Report an issue: GitHub.