dotnet/wpf · error · InvalidOperationException
SR.Format(SR.MemberNotAllowedDuringAddOrEdit, "RemoveAt")
Error message
SR.Format(SR.MemberNotAllowedDuringAddOrEdit, "RemoveAt")
What it means
RemoveAt(int) removes an item from the underlying collection via the view, but it is rejected with InvalidOperationException while an AddNew or EditItem transaction is in progress. Mutating the collection during an open transaction would corrupt the view's tracking of the new/edited item.
Solutions
- Call CommitEdit()/CancelEdit() and CommitNew()/CancelNew() before RemoveAt.
- Guard with !view.IsEditingItem && !view.IsAddingNew before removing.
- Cancel the in-flight transaction explicitly when the item being removed is the new/edited one.
- Use CollectionView's CanRemove check (base CollectionView.CanRemove) before calling RemoveAt.
Example fix
// before
view.RemoveAt(index);
// after
if (!view.IsEditingItem && !view.IsAddingNew && view.CanRemove)
view.RemoveAt(index);
else
view.CancelEdit(); view.CancelNew(); // close transactions, then retry Defensive patterns
Strategy: validation
Validate before calling
// C#
if (!view.IsEditingItem && !view.IsAddingNew && view.CanRemove)
view.RemoveAt(index); Type guard
bool CanRemoveAt(IEditableCollectionView v) => !v.IsEditingItem && !v.IsAddingNew;
Try / catch
try { view.RemoveAt(index); }
catch (InvalidOperationException ex) { Log.Warn("RemoveAt during add/edit", ex); view.CancelEdit(); view.CancelNew(); } Prevention
- Close add/edit transactions before any removal.
- Check CanRemove before removing.
- Disable delete UI while IsAddingNew/IsEditingItem.
When it happens
Trigger: Calling RemoveAt(index) when IsEditingItem or IsAddingNew is true — e.g. removing the currently-being-added or currently-being-edited row programmatically.
Common situations: A delete button handler that does not check for open add/edit transactions; DataGrid delete key pressed while a new row or cell edit is open; automation/scripts removing rows during batch edits.
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.Format(SR.MemberNotAllowedDuringAddOrEdit, "Remove")
- ArgumentNullException(nameof(value))
- (no message) NotSupportedException
- NotImplementedException (ConvertBack not supported)
- NotImplementedException (ConvertBack not supported)
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/ea8eb23a986c41cb.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Data/BindingListCollectionView.cs:872
/// <summary>
/// Return true if the view supports <seealso cref="Remove"/> and
/// <seealso cref="RemoveAt"/>.
/// </summary>
public bool CanRemove
{
get { return !IsEditingItem && !IsAddingNew && InternalList.AllowRemove; }
}
/// <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)