stride3d/stride · error · InvalidOperationException
Unable to remove this value at the given index because it…
Error message
Unable to remove this value at the given index because it wasn't found in the ObservableSet.
What it means
ObservableSet.RemoveItem must find the item at the given index in its internal HashSet. If hashSet.Remove fails, the list content and hash set are out of sync — a broken internal invariant the class never expects, so it throws a diagnostic InvalidOperationException.
Solutions
- Make items stored in an ObservableSet immutable, or at least keep GetHashCode/Equals stable while contained
- Ensure GetHashCode/Equals/comparer are consistent — do not mutate fields they depend on
- Avoid manipulating internal list/hashSet state outside the class API
- If you see it with correct usage, report as a library bug (the code comments it 'shouldn't happen')
Example fix
// before
class Item { public int Id; } // mutable Id used in GetHashCode
item.Id = 5; // hash changes -> unremovable
// after
class Item { public int Id { get; } } // immutable key, stable hash Defensive patterns
Strategy: validation
Validate before calling
// Ensure items' GetHashCode/Equals are stable: use immutable key fields
Try / catch
try { set.Remove(item); } catch (InvalidOperationException ex) { logger.Error(ex, "hashset/list desync in ObservableSet"); } Prevention
- Use immutable items or immutable hash keys in sets
- Never change fields used by GetHashCode/Equals while item is in the set
- Keep equality comparer consistent across the item's lifetime
When it happens
Trigger: External code tampering with the underlying list/hashset; a comparer or GetHashCode implementation whose hash changes after insertion, making stored items unfindable; bugs in overridden equality that make removal fail.
Common situations: Mutable items whose GetHashCode/Equals changes while stored in the set; custom equality comparers inconsistent with the stored state; concurrent modification corrupting internal state.
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
- Unable to set this value at the given index because this…
- An element with the same key has already been added.
- An id is both marked as deleted and associated to a key of…
- An item has been added to a collection that does not have a…
- An item with the same key has already been added.
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/c47b553c3e7abc10.
Report an issue: GitHub.
Appendix: source
Thrown at sources/presentation/Stride.Core.Presentation/Collections/ObservableSet.cs:109
{
var oldItem = base[index];
hashSet.Remove(oldItem);
if (!hashSet.Add(item))
{
// restore removed item
hashSet.Add(oldItem);
throw new InvalidOperationException("Unable to set this value at the given index because this value is already contained in this ObservableSet.");
}
base.SetItem(index, item);
}
protected override void RemoveItem(int index)
{
var item = base[index];
if (!hashSet.Remove(item))
{
// safety check: shouldn't happen. If it does, we have a failed logic somewhere.
throw new InvalidOperationException("Unable to remove this value at the given index because it wasn't found in the ObservableSet.");
}
base.RemoveItem(index);
}
/// <inheritdoc/>
[CollectionAccess(CollectionAccessType.None)]
public override string ToString()
{
return $"{{ObservableSet}} Count = {Count}";
}
#if SUPPORT_RANGE_ACTION
/// <summary>
/// Helper to raise a PropertyChanged event for the Count property
/// </summary>
private void OnCountPropertyChanged() => OnPropertyChanged(new PropertyChangedEventArgs("Count"));
/// <summary>View on GitHub (pinned to 96fad776d2)