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

  1. Make the source collection's notifications complete and ordered: every removed item must have been previously reported.
  2. Raise Reset instead of Remove when the collection state diverged from notification history.
  3. 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

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


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)