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
- Commit or cancel the pending transaction first: call CommitNew()/CancelNew() if IsAddingNew, or CommitEdit()/CancelEdit() if IsEditingItem, before RemoveAt.
- Guard the call: only call RemoveAt when !view.IsAddingNew && !view.IsEditingItem.
- 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
- Always close AddNew/EditItem transactions before programmatic mutations.
- Centralize view mutations in a helper that ends open transactions first.
- Disable delete commands while IsAddingNew || IsEditingItem (e.g. via CanExecute).
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
- SR.CurrentChangingCannotBeCanceled
- SR.Format(SR.MemberNotAllowedDuringAddOrEdit, "Refresh")
- SR.Format(SR.MemberNotAllowedDuringAddOrEdit, "Remove")
- Animation_Invalid_DefaultValue
- ArgumentOutOfRangeException
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)