JamesNK/Newtonsoft.Json · error · JsonSerializationException

Error setting value to '{0}' on '{1}'.

Error message

Error setting value to '{0}' on '{1}'.

What it means

Thrown by DynamicValueProvider.SetValue when the compiled dynamic-method setter fails while writing a value into a member (field or property) of the target object during serialization or deserialization. The '{0}' placeholder is the member name and '{1}' is the runtime type of the target. The original exception (e.g. TargetInvocationException, InvalidCastException) is preserved as the InnerException so the real cause is inspectable.

Source

Thrown at Src/Newtonsoft.Json/Serialization/DynamicValueProvider.cs:87

                if (_setter == null)
                {
                    _setter = DynamicReflectionDelegateFactory.Instance.CreateSet<object>(_memberInfo);
                }

#if DEBUG
                // dynamic method doesn't check whether the type is 'legal' to set
                // add this check for unit tests
                if (value != null && !ReflectionUtils.GetMemberUnderlyingType(_memberInfo).IsAssignableFrom(value.GetType()))
                {
                    throw new JsonSerializationException("Incompatible value. Cannot set {0} to type {1}.".FormatWith(CultureInfo.InvariantCulture, _memberInfo, value.GetType()));
                }
#endif

                _setter(target, value);
            }
            catch (Exception ex)
            {
                throw new JsonSerializationException("Error setting value to '{0}' on '{1}'.".FormatWith(CultureInfo.InvariantCulture, _memberInfo.Name, target.GetType()), ex);
            }
        }

        /// <summary>
        /// Gets the value.
        /// </summary>
        /// <param name="target">The target to get the value from.</param>
        /// <returns>The value.</returns>
        public object? GetValue(object target)
        {
            try
            {
                if (_getter == null)
                {
                    _getter = DynamicReflectionDelegateFactory.Instance.CreateGet<object>(_memberInfo);
                }

                return _getter(target);

View on GitHub (pinned to 4f73e74372)

Solutions

  1. Inspect ex.InnerException to find the real failure (cast, null-ref, setter validation) before changing anything.
  2. Verify the JSON value type matches the target property type; add a custom JsonConverter or a property-level converter for mismatches.
  3. If the property has no public setter, add one, use [JsonProperty] to map to a settable member, or use a constructor/[JsonConstructor] that accepts the value.
  4. Catch JsonSerializationException around JsonConvert.DeserializeObject and log Path (ex.Path) to locate the offending JSON member.

Example fix

// before: deserializing incompatible type
public class Model { public int Age { get; set; } }
var m = JsonConvert.DeserializeObject<Model>("{\"Age\":\"twenty\"}");
// after: map via string property + conversion
public class Model {
    [JsonProperty("age")] private string _ageRaw;
    public int Age => int.Parse(_ageRaw);
}
Defensive patterns

Strategy: try-catch

Validate before calling

if (value == null || !targetType.GetProperty(memberName)?.PropertyType.IsAssignableFrom(value.GetType()) == true) throw new ArgumentException("incompatible");

Type guard

// guard the value type before serialize
static bool CanAssign(Type memberType, object value) => value == null ? !memberType.IsValueType || Nullable.GetUnderlyingType(memberType) != null : memberType.IsAssignableFrom(value.GetType());

Try / catch

try {
    var obj = JsonConvert.DeserializeObject<T>(json, settings);
} catch (JsonSerializationException ex) when (ex.Message.Contains("Error setting value")) {
    logger.Error(ex, "Deser failed at {Path}: {Inner}", ex.Path, ex.InnerException?.Message);
    throw;
}

Prevention

When it happens

Trigger: Deserializing JSON into a property whose setter throws (e.g. a property with validation logic in the setter, a read-only auto-property with no setter, a type mismatch where the deserialized value cannot be assigned to the member type), or serializing where a getter is invoked but SetValue is used to populate during deserialization. Common during DeserializeObject<T> when the JSON contains a value incompatible with the target member type.

Common situations: Passing a JSON string into an int property, deserializing into a struct/record with init-only setters that the dynamic provider cannot bind, a property setter that throws ArgumentException on invalid input, value/type mismatches after a schema change, or a member that was renamed on the C# side but the JSON still carries the old name/type.

Related errors


AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07). Data as JSON: /api/errors/ddfd2c9700f3f85c. Report an issue: GitHub.