JamesNK/Newtonsoft.Json · error · ArgumentException
The value '{0}' is not of type '{1}' and cannot be used in t
Error message
The value '{0}' is not of type '{1}' and cannot be used in this generic collection. What it means
CollectionWrapper<T> is strongly typed to element type T. The non-generic IList path (Add, Insert, indexer set) calls VerifyValueType (CollectionWrapper.cs:300-306), which uses IsCompatibleObject to check the value is assignable to T. If the runtime type isn't compatible (e.g. adding an int into a List<string>), it throws ArgumentException with the value and the expected type T.
Source
Thrown at Src/Newtonsoft.Json/Utilities/CollectionWrapper.cs:304
object ICollection.SyncRoot
{
get
{
if (_syncRoot == null)
{
Interlocked.CompareExchange(ref _syncRoot, new object(), null);
}
return _syncRoot;
}
}
private static void VerifyValueType(object? value)
{
if (!IsCompatibleObject(value))
{
throw new ArgumentException("The value '{0}' is not of type '{1}' and cannot be used in this generic collection.".FormatWith(CultureInfo.InvariantCulture, value, typeof(T)), nameof(value));
}
}
private static bool IsCompatibleObject(object? value)
{
if (!(value is T) && (value != null || (typeof(T).IsValueType() && !ReflectionUtils.IsNullableType(typeof(T)))))
{
return false;
}
return true;
}
public object UnderlyingCollection => (object)_genericCollection! ?? _list!;
}
}View on GitHub (pinned to 4f73e74372)
Solutions
- Align the JSON array element type with the collection's element type T (e.g. send numbers for List<int>).
- Register a JsonConverter that converts each element to T before it reaches the collection.
- Widen the element type (use List<object> or a base type) if the array is heterogeneous.
- Enable TypeNameHandling and emit $type for polymorphic arrays.
- Validate the JSON payload against the expected schema before deserialization.
Example fix
// before
public List<int> Ids { get; set; } // JSON: ["42","43"] -> strings into int list
// after
public List<int> Ids { get; set; } // JSON: [42,43]
// OR add a converter that parses numeric strings to int Defensive patterns
Strategy: type-guard
Validate before calling
// Validate each element matches T before inserting via the non-generic IList path.
static void SafeAdd<T>(System.Collections.Generic.ICollection<T> c, object value) {
if (value is T t || (value == null && default(T) == null)) c.Add(t);
else throw new InvalidOperationException($"{value?.GetType()} is not compatible with {typeof(T)}.");
} Type guard
static bool IsCompatible<T>(object? value) => value is T || (value == null && (!typeof(T).IsValueType || System.Nullable.GetUnderlyingType(typeof(T)) != null));
Try / catch
try { list.Add(value); } catch (ArgumentException ex) when (ex.Message.Contains("is not of type")) { /* log schema mismatch; coerce or skip */ } Prevention
- Validate JSON array element types against the target element type before deserialization.
- Use strongly-typed models that match the JSON shape.
- Register converters that return the exact element type T.
- Enable TypeNameHandling for polymorphic arrays.
When it happens
Trigger: Deserializing a JSON array whose element CLR type (after conversion) doesn't match the target collection's element type T, with the value flowing through the IList.Add/Insert/indexer-set path. Also triggered by a custom converter returning the wrong element type.
Common situations: Mixed-type JSON arrays deserialized into strongly-typed List<T>; polymorphic payloads without TypeNameHandling; custom JsonConverter returning a type that isn't T; schema drift where a field changed type.
Related errors
- Wrapped ICollection<T> does not support indexer.
- Could not cast or convert from {0} to {1}.
- Unexpected value type when writing binary: {0}
- Unexpected value when converting date. Expected DateTime or
- Expected date object value.
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/15bd01742038de68.
Report an issue: GitHub.