gitbutlerapp/gitbutler · error
Visible worktree {name} was listed more than once
Error message
Visible worktree {name} was listed more than once What it means
When building a graph-rebase Editor from workspace tips, each visible (linked) worktree contributes one checkout keyed by its name. The builder inserts checkouts into a map keyed by name and bails if the same worktree name appears twice — one checkout per visible worktree is an invariant.
Source
Thrown at crates/but-rebase/src/graph_rebase/creation.rs:354
format!(
"Visible detached worktree {} HEAD {} is missing from the editor",
tip.name, tip.id
)
})?,
};
let name = tip.name.clone();
let checkout = Checkout::Worktree {
worktree_name: name.clone(),
selector: Selector {
id: selector,
revision: 0,
},
ref_name: tip.ref_name,
initial_head: tip.id,
merge_base_override: None,
};
if worktree_checkouts.insert(name.clone(), checkout).is_some() {
bail!("Visible worktree {name} was listed more than once");
}
}
let checkouts = worktree_checkouts
.into_values()
.chain(head_selectors.into_iter().map(|selector| Checkout::Head {
selector,
merge_base_override: None,
}))
.collect();
Ok(Self {
graph,
initial_references: references,
checkouts,
repo: repo.clone().with_object_memory(),
history: RevisionHistory::new(),
workspace,View on GitHub (pinned to caf1f223d3)
Solutions
- Deduplicate tip entries by worktree name before building the editor
- Fix the upstream listing so it comes from a single query/snapshot
- Refresh workspace state and rebuild the tip list if a rename is in flight
Example fix
// before let tips = old_tips.iter().chain(refreshed_tips.iter()); // may duplicate worktrees // after let mut seen = std::collections::HashSet::new(); let tips = tips.into_iter().filter(|t| seen.insert(t.name.clone()));
Defensive patterns
Strategy: validation
Validate before calling
// Rust: deduplicate worktree tips by name before building the editor
let mut seen = std::collections::HashSet::new();
let unique_tips: Vec<_> = tips
.into_iter()
.filter(|t| seen.insert(t.name.clone()))
.collect();
let editor = Editor::from_tips(unique_tips)?; Try / catch
Catch the bail, report which worktree name was duplicated, and rebuild the tip list from a single fresh snapshot before retrying.
Prevention
- Build worktree listings from one query/snapshot instead of concatenating sources
- Guard against duplicates at the listing boundary, especially around worktree renames
When it happens
Trigger: Constructing the editor from a tip list where two entries carry the same worktree `name`: duplicated rows from the listing query, or a hand-assembled spec list concatenating two snapshots.
Common situations: Workspace listings computed twice and concatenated; stale plus fresh entries around a worktree rename; custom tooling aggregating tips from multiple sources.
Related errors
- HTTP Error ${response.statusText}: ${text}
- Visible worktree {} changed since the editor was created: ex
- Visible worktree {worktree_name} HEAD changed shape during t
- File suffix '{}' is not allowed. Must be one of: {}
- Invalid selector set: This cannot be empty
AI-assisted analysis of gitbutlerapp/gitbutler@caf1f223d3 (2026-08-20).
Data as JSON: /api/errors/f0eff93c3dd0f236.
Report an issue: GitHub.