JamesNK/Newtonsoft.Json · error · JsonException
Multiple constructors with the JsonConstructorAttribute.
Error message
Multiple constructors with the JsonConstructorAttribute.
What it means
Only one constructor per type may carry [JsonConstructor]. GetAttributeConstructor enumerates constructors marked with JsonConstructorAttribute and throws a JsonException (line 617) if a second one is found. The attribute tells Json.NET which constructor to use for deserialization, so an ambiguous choice is rejected at contract build time.
Source
Thrown at Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs:617
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
private ConstructorInfo? GetAttributeConstructor(Type objectType)
{
IEnumerator<ConstructorInfo> en = objectType.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(c => c.IsDefined(typeof(JsonConstructorAttribute), true)).GetEnumerator();
if (en.MoveNext())
{
ConstructorInfo conInfo = en.Current;
if (en.MoveNext())
{
throw new JsonException("Multiple constructors with the JsonConstructorAttribute.");
}
return conInfo;
}
// little hack to get Version objects to deserialize correctly
if (objectType == typeof(Version))
{
return objectType.GetConstructor(new[] { typeof(int), typeof(int), typeof(int), typeof(int) });
}
return null;
}
private ConstructorInfo? GetImmutableConstructor(Type objectType, JsonPropertyCollection memberProperties)
{
IEnumerable<ConstructorInfo> constructors = objectType.GetConstructors();
IEnumerator<ConstructorInfo> en = constructors.GetEnumerator();View on GitHub (pinned to 4f73e74372)
Solutions
- Remove [JsonConstructor] from all but one constructor.
- If you need a specific deserialization path, keep the single most appropriate constructor and restructure the others without the attribute.
Example fix
// before
public class Widget {
[JsonConstructor] public Widget(int a) {}
[JsonConstructor] public Widget(int a, int b) {} // throws
}
// after
public class Widget {
public Widget(int a) {}
[JsonConstructor] public Widget(int a, int b) {}
} Defensive patterns
Strategy: validation
Validate before calling
// Fail fast in a unit test if more than one constructor is marked [JsonConstructor].
var tagged = typeof(T).GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.Where(c => c.IsDefined(typeof(JsonConstructorAttribute), true)).ToList();
if (tagged.Count > 1)
throw new InvalidOperationException("Multiple [JsonConstructor] constructors on " + typeof(T)); Type guard
static bool HasSingleJsonConstructor(Type t) =>
t.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)
.Count(c => c.IsDefined(typeof(JsonConstructorAttribute), true)) == 1; Try / catch
try { JsonConvert.DeserializeObject<T>(json); }
catch (JsonException ex) when (ex.Message.Contains("Multiple constructors"))
{
// remove [JsonConstructor] from all but one constructor
} Prevention
- Tag at most one constructor with [JsonConstructor].
- Add a reflection-based test that asserts the invariant for serializable types.
When it happens
Trigger: Decorating two (or more) constructors of the same class with [JsonConstructor], e.g. both a parameterized and a default constructor.
Common situations: Adding [JsonConstructor] to a new constructor while forgetting to remove it from the old one, or merging two classes during refactoring.
Related errors
- Constructor for '{0}' must have no parameters or a single pa
- Invalid extension data attribute on '{0}'. Member '{1}' must
- Invalid extension data attribute on '{0}'. Member '{1}' type
- Invalid attribute. Both '{0}' and '{1}' in type '{2}' have '
- Invalid Callback. Method '{3}' in type '{2}' has both '{0}'
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/255edadd5d34e8a2.
Report an issue: GitHub.