dotnet/wpf · critical · InvalidOperationException
SR.CannotFindRemovedItem
Error message
SR.CannotFindRemovedItem
What it means
During OnItemRemoved, the generator locates the block holding the removed item in its item map. If the item is not found in any realized block (the search reaches the sentinel _itemMap), the generator cannot know which unrealized block to update and throws InvalidOperationException SR.CannotFindRemovedItem, since silently skipping would corrupt the map.
Solutions
- Make the source collection's notifications complete and ordered: every removed item must have been previously reported.
- Raise Reset instead of Remove when the collection state diverged from notification history.
- Rebind ItemsSource (or refresh) if notifications were lost, so the generator rebuilds its map.
Example fix
// before
collection.Remove(x); // x was never announced via Add -> generator throws
// after
if (collection.Contains(x))
collection.Remove(x);
else
collectionOnReset(); // or raise Reset to resync the generator Defensive patterns
Strategy: try-catch
Validate before calling
if (!collection.Contains(item) && pendingRemovals.Contains(item))
raiseResetInsteadOfRemove(); // resync generator Try / catch
try { /* update binding */ }
catch (InvalidOperationException ex) when (ex.Message.Contains("removed item"))
{
itemsControl.Items.Refresh(); // rebuild generator map
} Prevention
- Ensure every Remove notification corresponds to a previously announced Add.
- Raise Reset when notification history may have diverged.
- Avoid dropping/batching CollectionChanged events.
When it happens
Trigger: A CollectionChanged Remove/Reset event reports an item the generator has no record of — e.g. the collection was modified without notifications, events were missed, or a custom collection raises Remove for an item it never raised Add for.
Common situations: Custom INotifyCollectionChanged sources with out-of-sync events; dropping/pausing events (e.g. during bulk edits) then raising a partial Remove; loading collections from another thread.
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
- SR.Generator_Inconsistent
- SR.Format(SR.CollectionAddEventMissingItem, item)
- SR.Freezable_UnexpectedChange
- SR.RangeActionsNotSupported
- InvalidOperationException
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/00db62d65b0cb6c9.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Controls/ItemContainerGenerator.cs:2250
if (itemIsInCurrentBlock)
{
// we don't know where it is in this block, so assume
// it's the very first item.
offsetFromBlockStart = 0;
position = new GeneratorPosition(containerIndex-1, 1);
break;
}
}
correctIndex += block.ItemCount;
containerIndex += block.ContainerCount;
}
if (block == _itemMap)
{
// There's no way of knowing which unrealized block it belonged to, so
// the data structure can't be updated correctly. Sound the alarm.
throw new InvalidOperationException(SR.CannotFindRemovedItem);
}
}
// establish the link from the container to the corresponding item
internal static void LinkContainerToItem(DependencyObject container, object item)
{
// always set the ItemForItemContainer property
container.ClearValue(ItemForItemContainerProperty);
container.SetValue(ItemForItemContainerProperty, item);
// for non-direct items, set the DataContext property
if (container != item)
{
#if DEBUG
// Some ancient code at this point handled the case when DataContext
// was set via an Expression (presumably a binding). I don't think
// this actually happens any more. Just in case...View on GitHub (pinned to 81131a70a4)