{"record":{"id":"f2a67482d2ae13af","repo":"JamesNK/Newtonsoft.Json","slug":"wrapped-icollection-t-does-not-support-indexer","errorCode":null,"errorMessage":"Wrapped ICollection<T> does not support indexer.","messagePattern":"Wrapped ICollection<T> does not support indexer\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"Src/Newtonsoft.Json/Utilities/CollectionWrapper.cs","lineNumber":263,"sourceCode":"                }\n            }\n        }\n\n        void IList.Remove(object? value)\n        {\n            if (IsCompatibleObject(value))\n            {\n                Remove((T)value!);\n            }\n        }\n\n        object? IList.this[int index]\n        {\n            get\n            {\n                if (_genericCollection != null)\n                {\n                    throw new InvalidOperationException(\"Wrapped ICollection<T> does not support indexer.\");\n                }\n\n                return _list![index];\n            }\n            set\n            {\n                if (_genericCollection != null)\n                {\n                    throw new InvalidOperationException(\"Wrapped ICollection<T> does not support indexer.\");\n                }\n\n                VerifyValueType(value);\n                _list![index] = (T?)value;\n            }\n        }\n\n        void ICollection.CopyTo(Array array, int arrayIndex)\n        {","sourceCodeStart":245,"sourceCodeEnd":281,"githubUrl":"https://github.com/JamesNK/Newtonsoft.Json/blob/4f73e74372445108d2c1bda37b36e6f5e43402e0/Src/Newtonsoft.Json/Utilities/CollectionWrapper.cs#L245-L281","documentation":"CollectionWrapper<T> internally adapts either an IList or an ICollection<T> into one IList view used during (de)serialization. When it was constructed from a plain ICollection<T> (e.g. HashSet<T>, or any collection that implements only ICollection<T> and not IList), positional access is impossible because ICollection<T> has no indexer. The getter of the IList.this[int] accessor throws InvalidOperationException to fail loudly rather than silently returning wrong data (the _genericCollection branch at CollectionWrapper.cs:261-263).","triggerScenarios":"Code (internal Newtonsoft pipeline, a custom IContractResolver/IConverter, or a caller that downcasts to IList) invokes wrapper[index] on a CollectionWrapper whose _list is null and _genericCollection is set — i.e. the wrapped object is a pure ICollection<T>, not also an IList.","commonSituations":"Serializing/deserializing types whose collection members are sets (HashSet<T>/ISet<T>) or custom collections implementing only ICollection<T>; custom contracts that force IList-based positional reads; third-party converters that assume positional access.","solutions":["Use an orderable collection type (List<T>, IList<T>, or T[]) for the property being (de)serialized instead of HashSet/ISet.","If you need set semantics, deserialize into a List<T> first, then build the set from it.","Avoid custom IContractResolver/converters that downcast collections to IList and call indexers on them.","Audit any registered third-party JsonConverter that touches collections by index and replace it with one that enumerates.","Expose the member as IList-backed so the wrapper takes the _list branch instead of the _genericCollection branch."],"exampleFix":"// before\npublic HashSet<string> Tags { get; set; } = new(); // ICollection<T> only, no indexer\n// after\npublic List<string> Tags { get; set; } = new();   // IList-backed, indexer works","handlingStrategy":"validation","validationCode":"// Before any positional access on a wrapped collection, confirm it is indexable.\nIList? indexable = collection as IList;\nif (indexable == null) {\n    // enumerate instead of indexing; do NOT call wrapper[i]\n    foreach (var item in (System.Collections.IEnumerable)collection) { /* ... */ }\n}","typeGuard":"static bool HasIndexer<T>(T collection) => collection is System.Collections.IList;","tryCatchPattern":"try { var x = wrapper[i]; } catch (InvalidOperationException) when (wrapped is ICollection<string>) { /* fall back to enumeration */ }","preventionTips":["Prefer List<T>/T[] for JSON collection properties so the wrapper takes the IList branch.","Never assume ICollection<T> supports positional access.","If you need a set, deserialize to List<T> then construct the set.","Audit custom converters/contract resolvers that touch collections by index."],"tags":["collections","serialization","newtonsoft-json","internal"],"analyzedSha":"4f73e74372445108d2c1bda37b36e6f5e43402e0","analyzedAt":"2026-08-07T06:10:08.596Z","schemaVersion":2},"datasetVersion":"2026-08-07T07:17:06.508Z"}