gitbutlerapp/gitbutler · error
BUG: a change from was pushed into a builder reading
Error message
BUG: a change from {} was pushed into a builder reading {} What it means
Internal invariant violation: an `UncommittedChanges` from a change source that is neither equal to the builder's source nor a named worktree was pushed into the builder. This indicates a bug in how the change was resolved or routed (sources should either match or be a worktree handled by the earlier branch).
Solutions
- Report this as a bug to the GitButler project with the command and reproduction steps
- Verify ids come from the current `but status` output of the same workspace (stale output can misattribute sources)
- Retry after refreshing resolution state; if reproducible, include `but` version in the report
Defensive patterns
Strategy: try-catch
Validate before calling
debug_assert_eq!(uncommitted.source, builder.source, "mismatched change source pushed into diff-specs builder");
Try / catch
if let Err(e) = result {
if e.to_string().starts_with("BUG: a change from") {
// collect diagnostics and report upstream; this is an internal invariant violation
report_bug(e);
} else { return Err(e.into()); }
} Prevention
- Keep source attribution consistent through id resolution
- Add assertions/tests covering non-worktree mismatched sources
- Report occurrences with `but` version and reproduction steps
When it happens
Trigger: `push_changes_from_uncommitted` sees `uncommitted.source != self.source` and `uncommitted.source.worktree_name()` returns None — i.e. a mismatched non-worktree source reached the builder, e.g. via `push_changes_from_id` with a wrongly attributed uncommitted id.
Common situations: Should not occur in normal use; encountered when a resolver returns uncommitted changes attributed to an unexpected source kind, or after internal refactors that change source tagging.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- A parent in the output graph is not a pick
- BUG: failed to apply head ref
- `but setup` cannot run from a linked worktree; run it from…
- Cannot compute diff specs for worktree
- Cannot currently work in repositories without a worktree
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/9fc7ce5989a3dd04.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but/src/utils/diff_specs.rs:114
anyhow::bail!("Cannot compute diff specs for committed hunks")
}
}
}
pub fn push_changes_from_uncommitted(
&mut self,
uncommitted: &UncommittedHunkOrFile,
) -> anyhow::Result<()> {
// Specs are built against one checkout's repository, so a hunk from
// another would silently address the wrong files. Operations that support
// worktree sources validate the selection and construct the builder via
// [`Self::for_change_source`]; the rest read the main worktree and refuse
// worktree hunks here.
if uncommitted.source != self.source {
if let Some(name) = uncommitted.source.worktree_name() {
anyhow::bail!("Cannot operate on uncommitted changes in worktree {name} yet");
}
anyhow::bail!(
"BUG: a change from {} was pushed into a builder reading {}",
uncommitted.source.describe(),
self.source.describe()
);
}
let hunks = uncommitted.hunks.iter().cloned();
self.push_hunks(hunks.map(|id_and_hunk| id_and_hunk.hunk))
}
pub fn push_changes_from_path_prefix(
&mut self,
hunks: &nonempty::NonEmpty<IdAndHunk>,
) -> anyhow::Result<()> {
self.push_hunks(hunks.iter().map(|id_and_hunk| id_and_hunk.hunk.clone()))
}
pub fn push_changes_from_committed_file(
&mut self,View on GitHub (pinned to 58e5313667)