JamesNK/Newtonsoft.Json · error · JsonException
Serialization Error Callback '{1}' in type '{0}' must have t
Error message
Serialization Error Callback '{1}' in type '{0}' must have two parameters of type '{2}' and '{3}'. What it means
An [OnError] callback must have exactly two parameters: a StreamingContext followed by an ErrorContext. IsValidCallback verifies parameter count and types and throws a JsonException (line 1339) otherwise. The error callback receives the serialization context and the error context so the handler can inspect and decide whether to swallow the error.
Source
Thrown at Src/Newtonsoft.Json/Serialization/DefaultContractResolver.cs:1339
{
throw new JsonException("Invalid Callback. Method '{3}' in type '{2}' has both '{0}' and '{1}'.".FormatWith(CultureInfo.InvariantCulture, prevAttributeType, attributeType, GetClrTypeFullName(method.DeclaringType!), method));
}
if (method.IsVirtual)
{
throw new JsonException("Virtual Method '{0}' of type '{1}' cannot be marked with '{2}' attribute.".FormatWith(CultureInfo.InvariantCulture, method, GetClrTypeFullName(method.DeclaringType!), attributeType));
}
if (method.ReturnType != typeof(void))
{
throw new JsonException("Serialization Callback '{1}' in type '{0}' must return void.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType!), method));
}
if (attributeType == typeof(OnErrorAttribute))
{
if (parameters == null || parameters.Length != 2 || parameters[0].ParameterType != typeof(StreamingContext) || parameters[1].ParameterType != typeof(ErrorContext))
{
throw new JsonException("Serialization Error Callback '{1}' in type '{0}' must have two parameters of type '{2}' and '{3}'.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType!), method, typeof(StreamingContext), typeof(ErrorContext)));
}
}
else
{
if (parameters == null || parameters.Length != 1 || parameters[0].ParameterType != typeof(StreamingContext))
{
throw new JsonException("Serialization Callback '{1}' in type '{0}' must have a single parameter of type '{2}'.".FormatWith(CultureInfo.InvariantCulture, GetClrTypeFullName(method.DeclaringType!), method, typeof(StreamingContext)));
}
}
prevAttributeType = attributeType;
return true;
}
internal static string GetClrTypeFullName(Type type)
{
if (type.IsGenericTypeDefinition() || !type.ContainsGenericParameters())View on GitHub (pinned to 4f73e74372)
Solutions
- Give the [OnError] method the signature 'void M(StreamingContext context, ErrorContext errorContext)'.
- Decide whether to handle the error by setting errorContext.Handled = true inside the callback.
Example fix
// before
public class Model {
[OnError]
internal void OnError(Exception ex) {} // wrong signature -> throws
}
// after
public class Model {
[OnError]
internal void OnError(StreamingContext context, ErrorContext errorContext) {
errorContext.Handled = true;
}
} Defensive patterns
Strategy: validation
Validate before calling
foreach (var m in typeof(T).GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).Where(m => m.IsDefined(typeof(OnErrorAttribute), false)))
{
var ps = m.GetParameters();
if (ps.Length != 2 || ps[0].ParameterType != typeof(StreamingContext) || ps[1].ParameterType != typeof(ErrorContext))
throw new InvalidOperationException($"OnError method {m.Name} must be (StreamingContext, ErrorContext).");
} Type guard
static bool OnErrorSignatureIsValid(MethodInfo m)
{
if (!m.IsDefined(typeof(OnErrorAttribute), false)) return true;
var ps = m.GetParameters();
return ps.Length == 2 && ps[0].ParameterType == typeof(StreamingContext) && ps[1].ParameterType == typeof(ErrorContext);
} Try / catch
try { JsonConvert.DeserializeObject<T>(json); }
catch (JsonException ex) when (ex.Message.Contains("Serialization Error Callback") && ex.Message.Contains("two parameters"))
{
// fix the OnError signature to (StreamingContext, ErrorContext)
} Prevention
- OnError methods must take (StreamingContext context, ErrorContext errorContext).
- Set errorContext.Handled = true to swallow specific errors.
When it happens
Trigger: An [OnError] method with zero, one, or three+ parameters, or with parameters of the wrong types (e.g. Exception instead of ErrorContext).
Common situations: Declaring an error handler with a single 'Exception' parameter by analogy with try/catch, or forgetting the StreamingContext parameter.
Related errors
- Invalid attribute. Both '{0}' and '{1}' in type '{2}' have '
- Invalid Callback. Method '{3}' in type '{2}' has both '{0}'
- Virtual Method '{0}' of type '{1}' cannot be marked with '{2
- Serialization Callback '{1}' in type '{0}' must return void.
- Serialization Callback '{1}' in type '{0}' must have a singl
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/c46dbb8ef724dc50.
Report an issue: GitHub.