dotnet/wpf · error · InvalidOperationException

SR.Format(SR.MemberNotAllowedDuringTransaction…

Error message

SR.Format(SR.MemberNotAllowedDuringTransaction, "CancelNew", "EditItem")

What it means

ArgumentException from BindingListCollectionView.CancelNew: the edit-transaction API is being used in the wrong order — CancelNew is called while the open transaction is an EditItem transaction (not AddNew), and this member is not allowed during that transaction.

Solutions

  1. Match cancel calls to the transaction type: call EndEdit/CancelEdit for EditItem, CancelNew only for AddNew
  2. Check IsAddingNew before calling CancelNew

Example fix

// before
if (view.IsAddingNew) view.CancelNew();

// after
if (view.IsEditingItem) view.CancelEdit();
if (view.IsAddingNew) view.CancelNew();
Defensive patterns

Strategy: validation

Validate before calling

// C#
if (view.IsEditingItem) view.CancelEdit();
if (view.IsAddingNew) view.CancelNew();

Type guard

bool CanCancelNew(IEditableCollectionView v) => !v.IsEditingItem && v.IsAddingNew;

Try / catch

try { view.CancelNew(); }
catch (InvalidOperationException ex) { Log.Warn("CancelNew blocked by open EditItem transaction", ex); }

Prevention

When it happens

Trigger: Calling EditItem() and then CancelNew() without closing the edit transaction via CommitEdit() or CancelEdit().

Common situations: A cancel button that calls both CancelEdit and CancelNew but in the wrong order; error-recovery code that resets add state while an item edit remains open; user hits Escape during a DataGrid edit that started from AddNew.

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/0e3e8a7357d4bc4b. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/BindingListCollectionView.cs:696

            if (_newItem != NoNewItem)
            {
                int delta = (NewItemPlaceholderPosition == NewItemPlaceholderPosition.AtBeginning) ? 1 : 0;
                NotifyCollectionChangedEventArgs args = ProcessCommitNew(_newItemIndex, _newItemIndex + delta);
                if (args != null)
                {
                    base.OnCollectionChanged(InternalList, args);
                }
            }
        }

        /// <summary>
        /// Complete the transaction started by <seealso cref="AddNew"/>.  The new
        /// item is removed from the collection.
        /// </summary>
        public void CancelNew()
        {
            if (IsEditingItem)
                throw new InvalidOperationException(SR.Format(SR.MemberNotAllowedDuringTransaction, "CancelNew", "EditItem"));
            VerifyRefreshNotDeferred();

            if (_newItem == NoNewItem)
                return;

            // cancel the AddNew
            ICancelAddNew ican = InternalList as ICancelAddNew;
            IEditableObject ieo;

            BindingOperations.AccessCollection(InternalList,
                () =>
                {
                    ProcessPendingChanges();

                    if (ican != null)
                    {
                        ican.CancelNew(_newItemIndex);
                    }

View on GitHub (pinned to 81131a70a4)