gitbutlerapp/gitbutler · error
Change to discard at
Error message
Change to discard at '{rela_path}' didn't have a last-known tracked state - this is a bug What it means
Thrown by hunk::restore_state_to_worktree when the ChangeState handed in has a null (all-zero) OID, meaning there is no known prior tracked blob to restore the file to. The library considers reaching this state a caller-side bug because changes that reach hunk restoration should always carry a resolved previous object id.
Solutions
- Resolve previous_state.id from the index or HEAD tree before calling; never pass a null OID.
- Check state.id.is_null() upstream and route such changes to whole-file or 'delete file' handling instead.
- If this arises from library-internal classification, report it as a bug with the reproduction.
Example fix
// before
hunk::restore_state_to_worktree(wt_change, state, ...)?;
// after
anyhow::ensure!(!state.id.is_null(), "no previous state for {}", wt_change.path);
hunk::restore_state_to_worktree(wt_change, state, ...)?; Defensive patterns
Strategy: validation
Validate before calling
fn has_previous_state(state: &ChangeState) -> bool {
!state.id.is_null()
} Prevention
- Always resolve previous_state OIDs from the index/HEAD before hunk restoration
- Never construct ChangeState manually without resolving the blob id
- Classify additions separately so they never reach the hunk-restore path
When it happens
Trigger: Calling restore_state_to_worktree with a previous_state whose id was never resolved from the index/HEAD (null hash), e.g. constructing ChangeState manually, or passing an Addition's state (no prior blob) into the hunk-restore path.
Common situations: Custom tooling that builds change descriptors without resolving OIDs, or a bug where an Addition is misclassified as a Modification before hunk restoration.
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
- Failed to assure that
- in commit , number of sides ( ) is not exactly one more…
- Missing reference which should be known to workspace…
- snapshot additional ref target is null
- snapshot checkout commit is null
AI-assisted analysis of gitbutlerapp/gitbutler@58e5313667 (2026-09-18).
Data as JSON: /api/errors/5d6cd399b122e99a.
Report an issue: GitHub.
Appendix: source
Thrown at crates/but-workspace/src/tree_manipulation/discard_worktree_changes.rs:225
/// Assume the resource to be restored doesn't exist as it was deleted.
Deleted,
/// A similar resource is in its place that needs to be updated.
Update,
}
/// Restore `state` by writing it into the worktree of `repo`, possibly re-adding or updating the
/// `index` with it so that it matches the worktree.
pub fn restore_state_to_worktree(
pipeline: &mut gix::filter::Pipeline<'_>,
index: &mut gix::index::State,
rela_path: &BStr,
state: ChangeState,
mode: RestoreMode,
path_check: &mut gix::status::plumbing::SymlinkCheck,
num_sorted_entries: &mut usize,
) -> anyhow::Result<()> {
if state.id.is_null() {
bail!(
"Change to discard at '{rela_path}' didn't have a last-known tracked state - this is a bug"
);
}
let mut update_index = |md| -> anyhow::Result<()> {
crate::commit_engine::index::upsert_index_entry(
index,
rela_path,
Some(&md),
state.id,
state.kind.into(),
gix::index::entry::Flags::UPDATE,
num_sorted_entries,
)?;
Ok(())
};
let repo = pipeline.repo;View on GitHub (pinned to 58e5313667)