{"record":{"id":"d353b5e612d2d49e","repo":"JamesNK/Newtonsoft.Json","slug":"converter-cannot-write-specified-value-to-json-0","errorCode":null,"errorMessage":"Converter cannot write specified value to JSON. {0} is required.","messagePattern":"Converter cannot write specified value to JSON\\. (.+?) is required\\.","errorType":"exception","errorClass":"JsonSerializationException","httpStatus":null,"severity":"error","filePath":"Src/Newtonsoft.Json/JsonConverter.cs","lineNumber":95,"sourceCode":"    }\n\n    /// <summary>\n    /// Converts an object to and from JSON.\n    /// </summary>\n    /// <typeparam name=\"T\">The object type to convert.</typeparam>\n    public abstract class JsonConverter<T> : JsonConverter\n    {\n        /// <summary>\n        /// Writes the JSON representation of the object.\n        /// </summary>\n        /// <param name=\"writer\">The <see cref=\"JsonWriter\"/> to write to.</param>\n        /// <param name=\"value\">The value.</param>\n        /// <param name=\"serializer\">The calling serializer.</param>\n        public sealed override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)\n        {\n            if (!(value != null ? value is T : ReflectionUtils.IsNullable(typeof(T))))\n            {\n                throw new JsonSerializationException(\"Converter cannot write specified value to JSON. {0} is required.\".FormatWith(CultureInfo.InvariantCulture, typeof(T)));\n            }\n            WriteJson(writer, (T?)value, serializer);\n        }\n\n        /// <summary>\n        /// Writes the JSON representation of the object.\n        /// </summary>\n        /// <param name=\"writer\">The <see cref=\"JsonWriter\"/> to write to.</param>\n        /// <param name=\"value\">The value.</param>\n        /// <param name=\"serializer\">The calling serializer.</param>\n        public abstract void WriteJson(JsonWriter writer, T? value, JsonSerializer serializer);\n\n        /// <summary>\n        /// Reads the JSON representation of the object.\n        /// </summary>\n        /// <param name=\"reader\">The <see cref=\"JsonReader\"/> to read from.</param>\n        /// <param name=\"objectType\">Type of the object.</param>\n        /// <param name=\"existingValue\">The existing value of object being read.</param>","sourceCodeStart":77,"sourceCodeEnd":113,"githubUrl":"https://github.com/JamesNK/Newtonsoft.Json/blob/4f73e74372445108d2c1bda37b36e6f5e43402e0/Src/Newtonsoft.Json/JsonConverter.cs#L77-L113","documentation":"Thrown by the sealed override JsonConverter<T>.WriteJson when the value handed to the converter is incompatible with the converter's generic type T. The base sealed method guards before delegating to the user-implemented WriteJson(writer, T?, serializer): if the value is non-null and not assignable to T (or null when T is not nullable), serialization is aborted with a JsonSerializationException naming the required type T. This protects the typed WriteJson from an invalid downcast.","triggerScenarios":"A JsonConverter<T> is registered (via attributes or settings.Converters) but the serializer offers it a value whose runtime type is not T (or a nullable T when null is passed). Common when a converter is applied too broadly via JsonSerializerSettings.Converters and gets invoked for unrelated types, or when CanConvert returns true for types the converter cannot actually write.","commonSituations":"Registering a single generic converter globally for many types; a polymorphic property whose declared type differs from T; CanConvert over-matching (returning true for base types or interfaces); passing null to a converter whose T is a non-nullable value type.","solutions":["Make CanConvert return true only for T (and Nullable<T> if intended) so the converter is never selected for other types.","Scope the converter with [JsonConverter(typeof(MyConverter<T>))] on the exact property/type instead of adding it to settings.Converters.","If you must handle null, ensure T is nullable (class or Nullable<T>) or override WriteJson to short-circuit nulls before the base guard."],"exampleFix":"// before\npublic override bool CanConvert(Type objectType) => true; // matches everything\n\n// after\npublic override bool CanConvert(Type objectType)\n    => objectType == typeof(MyType) || Nullable.GetUnderlyingType(objectType) == typeof(MyType);","handlingStrategy":"validation","validationCode":"var converters = settings.Converters;\nforeach (var c in converters)\n{\n    if (value != null && !c.CanConvert(value.GetType()))\n    {\n        // do not let this converter handle value\n    }\n}","typeGuard":"static bool CanConvertStrict<T>(JsonConverter<T> c, Type objectType)\n    where T : class\n    => objectType == typeof(T) || Nullable.GetUnderlyingType(objectType) == typeof(T);","tryCatchPattern":null,"preventionTips":["Implement CanConvert to match exactly the converter's T (and Nullable<T> if needed).","Prefer attribute-scoped converters ([JsonConverter]) over global settings.Converters.","Add unit tests asserting CanConvert returns false for sibling types."],"tags":["converter","type-mismatch","serialization"],"analyzedSha":"4f73e74372445108d2c1bda37b36e6f5e43402e0","analyzedAt":"2026-08-07T06:10:08.596Z","schemaVersion":2},"datasetVersion":"2026-08-07T07:17:06.508Z"}