gitbutlerapp/gitbutler · error
Commit {commit_ref} is not in a conflicted state. Only confl
Error message
Commit {commit_ref} is not in a conflicted state. Only conflicted commits can be resolved. What it means
Thrown by `but resolve <commit>` when entering resolution (edit) mode for a commit that is not marked conflicted. After resolving the id via IdMap, the command loads the commit with repo.find_commit() and checks commit.is_conflicted(); only conflicted commits (e.g. produced by a GitButler rebase/update that hit conflicts) may enter resolution mode.
Source
Thrown at crates/but/src/command/legacy/resolve.rs:207
}
_ => bail!("'{commit_id_str}' does not refer to a commit"),
}
}
fn enter_resolution(ctx: &mut Context, out: &mut OutputChannel, commit_id_str: &str) -> Result<()> {
let t = theme::get();
use gix::{prelude::ObjectIdExt as _, revision::walk::Sorting};
let (commit_gix_oid, commit_ref) = parse_commit_id(ctx, commit_id_str)?;
// Get the commit and check if it's conflicted
let repo = ctx.repo.get()?;
let commit = repo
.find_commit(commit_gix_oid)
.context("Failed to find commit")?;
if !commit.is_conflicted() {
bail!(
"Commit {commit_ref} is not in a conflicted state. Only conflicted commits can be resolved."
);
}
// Find which stack this commit belongs to
let stacks = crate::legacy::workspace::applied_stacks(ctx)?;
let mut found_stack_id = None;
'outer: for stack in &stacks {
// Check if this commit is in any of the stack's heads
// TODO(ctx): use `ws` for that.
// TODO(perf): This is likely to walk the whole graph.
for head in &stack.branches {
// Walk the commit history to see if our commit is in this stack
let traversal = head
.tip
.attach(&repo)
.ancestors()
.sorting(Sorting::BreadthFirst)View on GitHub (pinned to caf1f223d3)
Solutions
- Run `but resolve conflicts` (or `but status`) to list the commits that are actually conflicted right now and copy the current id
- If the commit was conflicted earlier but is fine now, nothing to do — conflicts were already resolved
- If you expected conflicts, run `but update`/the operation that produces conflicts again and re-list
Example fix
// before but resolve 4a9c1f2 // error: Commit 4a9c1f2 is not in a conflicted state... // after but resolve conflicts # list current conflicted commits but resolve <id-from-list>
Defensive patterns
Strategy: validation
Validate before calling
# list commits that are actually conflicted before targeting one
but resolve conflicts > /tmp/conflicts.txt
grep -q . /tmp/conflicts.txt || { echo 'nothing conflicted'; exit 0; }
# then pass an id from that listing to `but resolve <id>` Prevention
- Always source commit ids from `but resolve conflicts`, never from memory or history
- Treat 'not in a conflicted state' as informational — verify with the listing before retrying
- Remember resolutions rewrite descendant ids; stale ids go stale fast
When it happens
Trigger: Running `but resolve <commit-id>` (or a subcommand that starts edit mode) where the target commit is a normal commit, or a commit whose conflicts were already resolved by a previous run/rebase, so is_conflicted() returns false.
Common situations: Pointing at a commit oid from an older workspace state after conflicts were already fixed; passing a branch-tip or regular commit instead of the conflicted commit; re-running an old command from shell history after the workspace moved on.
Related errors
- Target ref required for remote url
- There are changes that differ from the original commit you w
- Branch "{name}" has no conflicted commits.
- Failed to communicate with LM Studio server: ${error instanc
- Invalid response: ${JSON.stringify(result)}
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/244f4feebc1445ce.
Report an issue: GitHub.