JamesNK/Newtonsoft.Json · error · InvalidOperationException
Wrapped ICollection<T> does not support IndexOf.
Error message
Wrapped ICollection<T> does not support IndexOf.
What it means
Thrown by CollectionWrapper<T>.IList.IndexOf when the wrapper was constructed around an ICollection<T> (which has no positional/index semantics) rather than an IList. The wrapper implements IList but only delegates index operations when the underlying collection is an IList; an ICollection<T> cannot honor IndexOf.
Source
Thrown at Src/Newtonsoft.Json/Utilities/CollectionWrapper.cs:201
return (Count - 1);
}
bool IList.Contains(object? value)
{
if (IsCompatibleObject(value))
{
return Contains((T)value!);
}
return false;
}
int IList.IndexOf(object? value)
{
if (_genericCollection != null)
{
throw new InvalidOperationException("Wrapped ICollection<T> does not support IndexOf.");
}
if (IsCompatibleObject(value))
{
return _list!.IndexOf((T)value!);
}
return -1;
}
void IList.RemoveAt(int index)
{
if (_genericCollection != null)
{
throw new InvalidOperationException("Wrapped ICollection<T> does not support RemoveAt.");
}
_list!.RemoveAt(index);View on GitHub (pinned to 4f73e74372)
Solutions
- Avoid treating ICollection<T>-only collections (HashSet, set-like) as ordered/indexed collections.
- If positional access is required, materialize the data into a List<T> first.
- Adjust any custom JsonConverter/contract so it does not request index-based operations on non-IList collections.
- Use JsonSerializer with collection types that implement IList<T> when index access is needed.
Example fix
// before: HashSet wrapped where index access attempted
var set = new HashSet<int>{1,2,3};
var wrapper = new CollectionWrapper<int>(set);
wrapper.IndexOf(2); // throws
// after: use a List for positional access
var list = new List<int>{1,2,3};
var wrapper = new CollectionWrapper<int>(list); Defensive patterns
Strategy: type-guard
Validate before calling
if (!(collection is IList)) throw new NotSupportedException("IndexOf requires an IList"); Type guard
static bool SupportsIndex<T>(ICollection<T> c) => c is IList;
Try / catch
try { var i = ((IList)wrapper).IndexOf(item); }
catch (InvalidOperationException ex) when (ex.Message.Contains("does not support IndexOf")) {
logger.Error(ex, "underlying collection is not positional; use a List<T>."); throw;
} Prevention
- Use List<T> (IList) backed collections when positional access is required.
- Avoid index operations on HashSet/set-like collections.
- Materialize non-indexed collections into List<T> before positional work.
- Audit custom converters that may call IndexOf on arbitrary collections.
When it happens
Trigger: Json.NET internally (during collection deserialization or serialization) calls IList.IndexOf on a CollectionWrapper that wraps a HashSet<T>, Dictionary<T>.ValueCollection, or any other ICollection<T> that is not an IList. Typically reached via a custom JsonConverter or contract that exposes such a collection where index access is attempted.
Common situations: Deserializing into or serializing a HashSet<T>/ISet<T>/KeyValuePair collection that a converter or custom contract treats as a list; using a CollectionWrapper directly in user code against a non-indexed collection; rare and usually surfaces from custom collection contracts.
Related errors
- Wrapped ICollection<T> does not support RemoveAt.
- Wrapped ICollection<T> does not support Insert.
- Newtonsoft.Json support for dynamic is not compatible with t
- Newtonsoft.Json support for dynamic is not compatible with t
- Newtonsoft.Json serialization is not compatible with trimmin
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/70821cc08e26e829.
Report an issue: GitHub.