JamesNK/Newtonsoft.Json · error · ArgumentException

Could not cast or convert from {0} to {1}.

Error message

Could not cast or convert from {0} to {1}.

What it means

EnsureTypeAssignable (ConvertUtils.cs:629-655) is the final fallback inside ConvertOrCast. After TryConvert fails, it checks direct assignability and any implicit/explicit cast operator (CastConverters). If the value still can't be assigned or cast to the target type, it throws ArgumentException at ConvertUtils.cs:654. The message reports the initial type (or {null}) and the target type.

Source

Thrown at Src/Newtonsoft.Json/Utilities/ConvertUtils.cs:654

                {
                    return value;
                }

                Func<object?, object?>? castConverter = CastConverters.Instance.Get(new StructMultiKey<Type, Type>(valueType, targetType));
                if (castConverter != null)
                {
                    return castConverter(value);
                }
            }
            else
            {
                if (ReflectionUtils.IsNullable(targetType))
                {
                    return null;
                }
            }

            throw new ArgumentException("Could not cast or convert from {0} to {1}.".FormatWith(CultureInfo.InvariantCulture, initialType?.ToString() ?? "{null}", targetType));
        }

        public static bool VersionTryParse(string input, [NotNullWhen(true)]out Version? result)
        {
#if HAVE_VERSION_TRY_PARSE
            return Version.TryParse(input, out result);
#else
            // improve failure performance with regex?
            try
            {
                result = new Version(input);
                return true;
            }
            catch
            {
                result = null;
                return false;
            }

View on GitHub (pinned to 4f73e74372)

Solutions

  1. Align the .NET model with the actual JSON shape (e.g. model a nested object instead of a primitive).
  2. Register a JsonConverter for the mismatched type.
  3. For dynamic/loosely-typed payloads, deserialize to JToken/JObject and inspect manually.
  4. Add an implicit/explicit conversion operator or TypeConverter between the source and target types.
  5. Enable TypeNameHandling if the payload is polymorphic.

Example fix

// before
public class Item { public int Count { get; set; } } // JSON: "count": { "value": 3 }
// after
public class Item { public Count Count { get; set; } } // model the nested object
Defensive patterns

Strategy: try-catch

Validate before calling

// Before deserialization, sanity-check that the JSON token kind matches the model field kind.
var token = JToken.Parse(json);
if (token["count"] is JObject) throw new InvalidOperationException("'count' is an object, model expects a scalar.");

Type guard

static bool AssignableTo(object value, Type target) => value == null ? ReflectionUtils.IsNullable(target) : target.IsAssignableFrom(value.GetType());

Try / catch

try { return JsonConvert.DeserializeObject<T>(json, settings); } catch (ArgumentException ex) when (ex.Message.Contains("Could not cast or convert")) { /* deserialize to JToken and map manually */ }

Prevention

When it happens

Trigger: The deserialization/conversion pipeline lands a value whose runtime type can neither be converted (TryConvert fails) nor cast (not assignable, no cast operator) to the target property type.

Common situations: JSON shape doesn't match the .NET model (object where a primitive is expected, or vice versa); missing custom converters; version skew where a member changed type; polymorphic values without TypeNameHandling.

Related errors


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