JamesNK/Newtonsoft.Json · error · JsonSerializationException
Null collection of serializable members returned.
Error message
Null collection of serializable members returned.
What it means
CreateProperties calls the virtual GetSerializableMembers and throws a JsonSerializationException (line 1376) if it returns null. An empty list is acceptable; null is not, because the property-building loop would fail. This is a contract for anyone overriding GetSerializableMembers in a custom contract resolver.
Source
Thrown at Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs:1376
{
return type.FullName!;
}
return "{0}.{1}".FormatWith(CultureInfo.InvariantCulture, type.Namespace, type.Name);
}
/// <summary>
/// Creates properties for the given <see cref="JsonContract"/>.
/// </summary>
/// <param name="type">The type to create properties for.</param>
/// /// <param name="memberSerialization">The member serialization mode for the type.</param>
/// <returns>Properties for the given <see cref="JsonContract"/>.</returns>
protected virtual IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
List<MemberInfo> members = GetSerializableMembers(type);
if (members == null)
{
throw new JsonSerializationException("Null collection of serializable members returned.");
}
DefaultJsonNameTable nameTable = GetNameTable();
JsonPropertyCollection properties = new JsonPropertyCollection(type);
foreach (MemberInfo member in members)
{
JsonProperty property = CreateProperty(member, memberSerialization);
if (property != null)
{
// nametable is not thread-safe for multiple writers
lock (nameTable)
{
property.PropertyName = nameTable.Add(property.PropertyName!);
}
View on GitHub (pinned to 4f73e74372)
Solutions
- Return an empty list (e.g. 'return new List<MemberInfo>();') instead of null from the override.
- If you intended to skip property creation, return an empty collection rather than null.
Example fix
// before
protected override IList<MemberInfo> GetSerializableMembers(Type objectType) {
var members = base.GetSerializableMembers(objectType).Where(Keep);
return members.Any() ? members.ToList() : null; // throws
}
// after
protected override IList<MemberInfo> GetSerializableMembers(Type objectType) {
return base.GetSerializableMembers(objectType).Where(Keep).ToList();
} Defensive patterns
Strategy: validation
Validate before calling
// If you ship a custom resolver, assert in tests that GetSerializableMembers never returns null.
var resolver = new MyCustomResolver();
foreach (var t in typesUnderTest)
{
var members = resolver.GetSerializableMembers(t);
if (members == null)
throw new InvalidOperationException($"GetSerializableMembers returned null for {t}.");
} Type guard
// n/a: this is a contract for an override, not a runtime type test
Try / catch
try { JsonConvert.SerializeObject(value, settings); }
catch (JsonSerializationException ex) when (ex.Message == "Null collection of serializable members returned.")
{
// fix the custom resolver override to return an empty list instead of null
} Prevention
- Never return null from a GetSerializableMembers override; return an empty list.
- Use '.ToList()' on filtered member queries to guarantee a non-null collection.
When it happens
Trigger: A custom DefaultContractResolver (or IContractResolver) override of GetSerializableMembers that returns null instead of a (possibly empty) IList<MemberInfo>.
Common situations: Writing a custom resolver and short-circuiting with 'return null;' when no members match a filter.
Related errors
- No object created.
- type
- Invalid extension data attribute on '{0}'. Member '{1}' must
- Invalid extension data attribute on '{0}'. Member '{1}' type
- Cannot set value onto extension data member '{0}'. The exten
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/007c52be09c6f710.
Report an issue: GitHub.