JamesNK/Newtonsoft.Json · error · ArgumentNullException
type
Error message
type
What it means
CamelCasePropertyNamesContractResolver.ResolveContract throws an ArgumentNullException when its 'type' argument is null (line 66). The resolver cannot build or look up a JsonContract for an unknown type, so the very first statement guards against a null Type. This is the standard argument-validation contract for the method.
Source
Thrown at Src/Newtonsoft.Json/Serialization/CamelCasePropertyNamesContractResolver.cs:66
public CamelCasePropertyNamesContractResolver()
{
NamingStrategy = new CamelCaseNamingStrategy
{
ProcessDictionaryKeys = true,
OverrideSpecifiedNames = true
};
}
/// <summary>
/// Resolves the contract for a given type.
/// </summary>
/// <param name="type">The type to resolve a contract for.</param>
/// <returns>The contract for a given type.</returns>
public override JsonContract ResolveContract(Type type)
{
if (type == null)
{
throw new ArgumentNullException(nameof(type));
}
// for backwards compatibility the CamelCasePropertyNamesContractResolver shares contracts between instances
StructMultiKey<Type, Type> key = new StructMultiKey<Type, Type>(GetType(), type);
Dictionary<StructMultiKey<Type, Type>, JsonContract>? cache = _contractCache;
if (cache == null || !cache.TryGetValue(key, out JsonContract? contract))
{
contract = CreateContract(type);
// avoid the possibility of modifying the cache dictionary while another thread is accessing it
lock (TypeContractCacheLock)
{
cache = _contractCache;
Dictionary<StructMultiKey<Type, Type>, JsonContract> updatedCache = (cache != null)
? new Dictionary<StructMultiKey<Type, Type>, JsonContract>(cache)
: new Dictionary<StructMultiKey<Type, Type>, JsonContract>();
updatedCache[key] = contract;
View on GitHub (pinned to 4f73e74372)
Solutions
- Null-check the Type before calling ResolveContract and surface a clearer error upstream.
- Fix the caller that produces a null Type (ensure typeof(T) / GetType() never yields null before reaching the resolver).
- If the type genuinely depends on input, fall back to a default type (e.g. typeof(object)) instead of null.
Example fix
// before
JsonContract contract = resolver.ResolveContract(maybeNullType);
// after
if (maybeNullType == null) throw new InvalidOperationException("Type was not resolved from input.");
JsonContract contract = resolver.ResolveContract(maybeNullType); Defensive patterns
Strategy: validation
Validate before calling
if (type == null) throw new ArgumentNullException(nameof(type)); var contract = resolver.ResolveContract(type);
Type guard
static bool IsResolvableType(Type? t) => t != null && !t.IsPointer && !t.IsByRef;
Try / catch
try { var contract = resolver.ResolveContract(type); }
catch (ArgumentNullException) when (type == null)
{
// log and return a safe default contract or rethrow with context
} Prevention
- Always null-check the Type before resolving a contract.
- Trace where the Type originates (reflection, $type, generic inference) and ensure it is never null.
When it happens
Trigger: Calling resolver.ResolveContract(null) directly, or passing a null Type that flows from reflection/serialization settings into the resolver. Also reachable when a generic serializer helper loses its type argument (e.g. typeof(T) where T is unconstrained and resolves to null at runtime through dynamic dispatch).
Common situations: Helpers like SerializeObject<T> where T is inferred as a non-type, deserialization pipelines that derive the type from JSON and pass null when $type is absent, or manually constructing the resolver and forgetting the type argument.
Related errors
- An ObjectId must be 12 bytes
- Cannot convert date value that is before Unix epoch of 00:00
- Namespace attribute must have a value.
- Delimiter must be a single or double quote.
- Value must be positive.
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/9976fe243e20fe75.
Report an issue: GitHub.