affaan-m/ECC · error
Worktree {} has uncommitted changes; commit or discard them
Error message
Worktree {} has uncommitted changes; commit or discard them before rebasing What it means
Thrown by rebase_onto_base at ecc2/src/worktree/mod.rs:915 as the very first guard. It calls has_uncommitted_changes(worktree) (which runs git status --porcelain in the worktree path) and bails if anything is dirty, because `git rebase <base_branch>` requires a clean working tree — git itself would refuse or, worse, stash-and-partially-replay.
Source
Thrown at ecc2/src/worktree/mod.rs:915
anyhow::bail!("git merge failed: {stderr}");
}
let merged_output = format!(
"{}\n{}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)
);
Ok(MergeOutcome {
branch: worktree.branch.clone(),
base_branch: worktree.base_branch.clone(),
already_up_to_date: merged_output.contains("Already up to date."),
})
}
pub fn rebase_onto_base(worktree: &WorktreeInfo) -> Result<RebaseOutcome> {
if has_uncommitted_changes(worktree)? {
anyhow::bail!(
"Worktree {} has uncommitted changes; commit or discard them before rebasing",
worktree.branch
);
}
let repo_root = base_checkout_path(worktree)?;
let before_head = branch_head_oid_in_repo(&repo_root, &worktree.branch)?;
let output = Command::new("git")
.arg("-C")
.arg(&worktree.path)
.args(["rebase", &worktree.base_branch])
.output()
.context("Failed to rebase worktree branch onto base")?;
if !output.status.success() {
let abort_output = Command::new("git")
.arg("-C")
.arg(&worktree.path)View on GitHub (pinned to 01e15490f0)
Solutions
- Commit the worktree's changes first: `git -C <worktree_path> add -A && git -C <worktree_path> commit -m 'wip'`, then retry rebase_onto_base.
- If the changes are unwanted, discard them: `git -C <worktree_path> checkout -- .` (and clean untracked files if appropriate).
- If you want to keep edits but not commit, git stash inside the worktree before rebasing and pop after: `git -C <worktree_path> stash`.
- Ensure ECC's session lifecycle commits agent edits before exposing a rebase entry point.
Example fix
// before
rebase_onto_base(&worktree)?;
// after: auto-commit dirty worktree before rebasing
if has_uncommitted_changes(&worktree)? {
Command::new("git").arg("-C").arg(&worktree.path)
.args(["add", "-A"]).status()?;
Command::new("git").arg("-C").arg(&worktree.path)
.args(["commit", "-m", "wip: pre-rebase snapshot"]).status()?;
}
rebase_onto_base(&worktree)?; Defensive patterns
Strategy: validation
Validate before calling
if has_uncommitted_changes(&worktree)? {
Command::new("git").arg("-C").arg(&worktree.path)
.args(["add", "-A"]).status()?;
Command::new("git").arg("-C").arg(&worktree.path)
.args(["commit", "-m", "chore: snapshot before rebase"]).status()?;
}
// now safe to call rebase_onto_base Type guard
null
Try / catch
match rebase_onto_base(&worktree) {
Ok(o) => o,
Err(e) if e.to_string().contains("uncommitted changes; commit or discard them before rebasing") => {
Command::new("git").arg("-C").arg(&worktree.path)
.args(["add", "-A"]).status()?;
Command::new("git").arg("-C").arg(&worktree.path)
.args(["commit", "-m", "wip"]).status()?;
rebase_onto_base(&worktree)?
}
Err(e) => return Err(e),
} Prevention
- Make ECC sessions auto-commit before exposing rebase/merge entry points.
- Block external editors from writing to worktree paths during rebase windows.
- Add a UI indicator showing dirty/clean state on the worktree before the rebase button is enabled.
- Run rebase inside a tmux/lock guard so concurrent invocations serialize.
When it happens
Trigger: Calling rebase_onto_base on a worktree where the agent left uncommitted edits; an editor or build tool modified tracked files inside the worktree path; staged changes exist (git status -s returns non-empty); untracked files are present (status --porcelain lists them with ??).
Common situations: Agent session wrote code to the worktree but did not commit before the user invoked rebase; formatter reformatted files on save after the last commit; leftover conflict markers from a previous rebase attempt; build artifacts (dist/, target/) are tracked or appear as untracked-but-relevant.
Related errors
- Worktree {} has uncommitted changes; commit or discard them
- Repository root {} has uncommitted changes; commit or stash
- git rebase failed: {}{}
- Cannot rebase active session {} while it is {}
- git worktree add failed: {stderr}
AI-assisted analysis of affaan-m/ECC@01e15490f0 (2026-08-13).
Data as JSON: /api/errors/c90e32264fc0d419.
Report an issue: GitHub.