dotnet/wpf · error · InvalidOperationException

SR.Format(SR.MemberNotAllowedDuringAddOrEdit, "RemoveAt")

Error message

SR.Format(SR.MemberNotAllowedDuringAddOrEdit, "RemoveAt")

What it means

ListCollectionView.RemoveAt throws InvalidOperationException when the view is in the middle of an AddNew or EditItem transaction. Removing items from the view is not allowed while a new item is being added or an existing one edited, because the remove would corrupt the pending transaction state.

Solutions

  1. Commit or cancel the pending transaction first: call CommitNew()/CancelNew() if IsAddingNew, or CommitEdit()/CancelEdit() if IsEditingItem, before RemoveAt.
  2. Guard the call: only call RemoveAt when !view.IsAddingNew && !view.IsEditingItem.
  3. If the removal originates from UI events, defer it (Dispatcher.BeginInvoke) until after the edit transaction ends.

Example fix

// before
collectionView.RemoveAt(index);

// after
if (collectionView.IsAddingNew) collectionView.CommitNew();
if (collectionView.IsEditingItem) collectionView.CommitEdit();
collectionView.RemoveAt(index);
Defensive patterns

Strategy: validation

Validate before calling

if (view.IsAddingNew) view.CommitNew();
if (view.IsEditingItem) view.CommitEdit();
// now safe:
view.RemoveAt(index);

Type guard

bool CanMutate(ICollectionView v) => !v.IsAddingNew && !v.IsEditingItem;

Try / catch

try { view.RemoveAt(index); }
catch (InvalidOperationException ex) when (ex.Message.Contains("NotAllowedDuringAddOrEdit"))
{ /* end transaction and retry, or surface message */ }

Prevention

When it happens

Trigger: Calling view.RemoveAt(index) while IsAddingNew is true (after AddNew without CommitNew/CancelNew) or while IsEditingItem is true (after EditItem without CommitEdit/CancelEdit).

Common situations: DataGrid or ItemsControl editing sessions left open (user still editing a row) while code removes a row programmatically; batch-delete code running while an add-new row is pending in the UI.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/ab23d3e6d7774138. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/ListCollectionView.cs:1050

        /// <summary>
        /// Return true if the view supports <seealso cref="Remove"/> and
        /// <seealso cref="RemoveAt"/>.
        /// </summary>
        public bool CanRemove
        {
            get { return !IsEditingItem && !IsAddingNew && !SourceList.IsFixedSize; }
        }

        /// <summary>
        /// Remove the item at the given index from the underlying collection.
        /// The index is interpreted with respect to the view (not with respect to
        /// the underlying collection).
        /// </summary>
        public void RemoveAt(int index)
        {
            if (IsEditingItem || IsAddingNew)
                throw new InvalidOperationException(SR.Format(SR.MemberNotAllowedDuringAddOrEdit, "RemoveAt"));
            VerifyRefreshNotDeferred();

            RemoveImpl(GetItemAt(index), index);
        }

        /// <summary>
        /// Remove the given item from the underlying collection.
        /// </summary>
        public void Remove(object item)
        {
            if (IsEditingItem || IsAddingNew)
                throw new InvalidOperationException(SR.Format(SR.MemberNotAllowedDuringAddOrEdit, "Remove"));
            VerifyRefreshNotDeferred();

            int index = InternalIndexOf(item);
            if (index >= 0)
            {
                RemoveImpl(item, index);

View on GitHub (pinned to 81131a70a4)