zed-industries/zed · error
{:?} is in non-existent deleted hunk
Error message
{:?} is in non-existent deleted hunk What it means
When a multibuffer renders a diff, deleted (base-only) hunks become DiffTransform::DeletedHunk entries whose text lives in the diff's base text. Computing a text summary for a range that intersects such a hunk requires that base text; if diff_state(buffer_id) no longer provides one, the code panics with '<range start> is in non-existent deleted hunk'. The snapshot still contains deleted-hunk geometry for a buffer whose diff base was dropped or replaced.
Source
Thrown at crates/multi_buffer/src/multi_buffer.rs:4637
}
pub fn max_row(&self) -> MultiBufferRow {
MultiBufferRow(self.text_summary().lines.row)
}
pub fn text_summary(&self) -> MBTextSummary {
self.diff_transforms.summary().output
}
pub fn text_summary_for_range<MBD, O>(&self, range: Range<O>) -> MBD
where
MBD: MultiBufferDimension + AddAssign,
O: ToOffset,
{
let range = range.start.to_offset(self)..range.end.to_offset(self);
let mut cursor = self
.diff_transforms
.cursor::<Dimensions<MultiBufferOffset, ExcerptOffset>>(());
cursor.seek(&range.start, Bias::Right);
let Some(first_transform) = cursor.item() else {
return MBD::from_summary(&MBTextSummary::default());
};
let diff_transform_start = cursor.start().0;
let diff_transform_end = cursor.end().0;
let diff_start = range.start;
let start_overshoot = diff_start - diff_transform_start;
let end_overshoot = std::cmp::min(range.end, diff_transform_end) - diff_transform_start;
let mut result = match first_transform {
DiffTransform::BufferContent { .. } => {
let excerpt_start = cursor.start().1 + start_overshoot;
let excerpt_end = cursor.start().1 + end_overshoot;
self.text_summary_for_excerpt_offset_range(excerpt_start..excerpt_end)
}View on GitHub (pinned to 5a9b9558db)
Solutions
- Obtain a new multibuffer snapshot after any diff/base-text change and recompute summaries from it
- Keep the diff base alive (retain the base buffer in the diff state) for as long as snapshots containing DeletedHunk transforms are in use
- When invalidating diffs, clear or replace the deleted-hunk transforms in the same edit so stale geometry cannot be queried
- If it reproduces, report it upstream with steps - this is an internal consistency invariant
Example fix
// before: summary computed on a snapshot whose diff base is gone let summary = old_snapshot.text_summary_for_range(range); // panics inside DeletedHunk // after: refresh the snapshot after diff invalidation, then compute apply_diff_invalidation(&mut multi_buffer, cx); let snapshot = multi_buffer.read(cx).snapshot(cx); let summary = snapshot.text_summary_for_range(range);
Defensive patterns
Strategy: validation
Validate before calling
// never query summaries on a snapshot older than the last diff update: // re-snapshot right before summarizing ranges that can cross deleted hunks let snapshot = multi_buffer.read(cx).snapshot(cx); let summary = snapshot.text_summary_for_range(range);
Prevention
- Invalidate cached summaries and layout state whenever a buffer's diff state changes
- Keep diff bases alive as long as snapshots containing DeletedHunk transforms are in use
- Apply diff-base removal and transform recomputation in one atomic edit so stale geometry is never observable
When it happens
Trigger: Calling summary_for_range-style APIs (used by layout, scrolling, offset math) over a range crossing a DeletedHunk after the buffer's diff base was removed - the diff was invalidated, the base buffer closed, or the snapshot predates a diff rebuild that dropped base text.
Common situations: Races between git changes on disk and in-memory diff bases; closing the base/diff buffer while a snapshot with deleted hunks is still used for layout; partial updates that strip diff bases without recomputing the transforms that reference them.
Related errors
- anchor's path was never added to multibuffer
- row out of range
- invalid display row {}
- blocking sender returned without value
- byte index {} is out of bounds of rope (length: {})
AI-assisted analysis of zed-industries/zed@5a9b9558db (2026-08-20).
Data as JSON: /api/errors/afaca4a9e2c6e4c3.
Report an issue: GitHub.