gitbutlerapp/gitbutler · error · anyhow::Error
Two conflicted paths normalize to the same value ({:?}); res
Error message
Two conflicted paths normalize to the same value ({:?}); resolve this commit manually instead What it means
index_files_by_path() keys every conflicted file of the commit by its normalized path (trim, backslashes to slashes, strip leading ./, collapse duplicate slashes). If two distinct conflicted paths normalize to the same key, a path-addressed spec would be ambiguous between two files, so the whole request is rejected with advice to resolve manually. This is a property of the commit itself, not of the specs - every resolve call on such a commit fails.
Source
Thrown at crates/but-api/src/resolve/apply.rs:141
file.hunks.len(),
if file.hunks.len() == 1 { "" } else { "s" },
hunk
);
}
Ok((file_index, hunk - 1))
}
/// Map normalized request paths to file indices, rejecting collisions.
pub(crate) fn index_files_by_path(
request: &ResolutionRequest,
) -> anyhow::Result<BTreeMap<String, usize>> {
let mut files_by_path = BTreeMap::new();
for (index, file) in request.files.iter().enumerate() {
if files_by_path
.insert(normalize_path(&file.path), index)
.is_some()
{
bail!(
"Two conflicted paths normalize to the same value ({:?}); resolve this commit manually instead",
normalize_path(&file.path)
);
}
}
Ok(files_by_path)
}
/// Reject content that contains a conflict-marker-shaped line.
pub(crate) fn ensure_no_markers(content: &str, path: &str) -> anyhow::Result<()> {
if let Some(marker) = content
.lines()
.map(|line| line.strip_suffix('\r').unwrap_or(line))
.find(|line| is_marker_shaped(line))
{
bail!("The resolution for \"{path}\" contains a conflict marker ({marker:?})");
}
Ok(())View on GitHub (pinned to caf1f223d3)
Solutions
- Resolve this particular commit manually, as the message says (edit mode or git mergetool outside the API)
- Check the commit's conflicted paths for separator-only or './'-only differences and normalize them in the merge
- If reproducible, report it - it is a defensive guard against ambiguous path addressing, and the input commit shape is worth a bug report
Defensive patterns
Strategy: try-catch
Try / catch
try {
await api.resolveCommitConflictHunks(commitId, specs);
} catch (err) {
if (String(err).includes('normalize to the same value')) {
// commit-level ambiguity: no spec shape can fix it
routeToManualResolution(commitId);
} else throw err;
} Prevention
- Expect this on commits mixing path separators (rename/rename on case-insensitive filesystems) - route them to manual resolution proactively
- When creating conflicted commits programmatically, emit one canonical path spelling
- Do not retry with different path spellings; the collision is between the commit's own files
When it happens
Trigger: A conflicted commit containing two paths that differ only in separator style or redundant components - e.g. 'dir/file' and '.\\dir\\file', or 'a//b' and 'a/b' - which can appear after rename/rename conflicts on case-insensitive filesystems or unusual merge tooling. Any resolve_commit_conflict_hunks / AI resolve call on that commit then bails during validation.
Common situations: Case-renames on macOS/Windows producing both spellings; merge commits created by external tools that mixed path separators; repos with paths that only differ pre-normalization.
Related errors
- Conflict {} of "{}" was addressed more than once
- Validation
- No resolutions were provided
- Invalid message format
- HTTP Error ${response.statusText}: ${text}
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/7d18c93483827c4c.
Report an issue: GitHub.