{"record":{"id":"2cf3f37cc07f0b41","repo":"JamesNK/Newtonsoft.Json","slug":"customcreationconverter-should-only-be-used-while","errorCode":null,"errorMessage":"CustomCreationConverter should only be used while deserializing.","messagePattern":"CustomCreationConverter should only be used while deserializing\\.","errorType":"exception","errorClass":"NotSupportedException","httpStatus":null,"severity":"error","filePath":"Src/Newtonsoft.Json/Converters/CustomCreationConverter.cs","lineNumber":49,"sourceCode":"namespace Newtonsoft.Json.Converters\n{\n    /// <summary>\n    /// Creates a custom object.\n    /// </summary>\n    /// <typeparam name=\"T\">The object type to convert.</typeparam>\n    [RequiresUnreferencedCode(MiscellaneousUtils.TrimWarning)]\n    [RequiresDynamicCode(MiscellaneousUtils.AotWarning)]\n    public abstract class CustomCreationConverter<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 override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)\n        {\n            throw new NotSupportedException(\"CustomCreationConverter should only be used while deserializing.\");\n        }\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>\n        /// <param name=\"serializer\">The calling serializer.</param>\n        /// <returns>The object value.</returns>\n        public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)\n        {\n            if (reader.TokenType == JsonToken.Null)\n            {\n                return null;\n            }\n\n            T value = Create(objectType);","sourceCodeStart":31,"sourceCodeEnd":67,"githubUrl":"https://github.com/JamesNK/Newtonsoft.Json/blob/4f73e74372445108d2c1bda37b36e6f5e43402e0/Src/Newtonsoft.Json/Converters/CustomCreationConverter.cs#L31-L67","documentation":"Thrown by CustomCreationConverter<T>.WriteJson as a NotSupportedException. This converter family is read-only (CanWrite returns false); it exists to let you override Create(Type) to supply a target instance during deserialization. Serializing with it is unsupported by design, so calling WriteJson directly or forcing serialization through it triggers the error.","triggerScenarios":"Subclassing CustomCreationConverter<T> and then serializing (not deserializing) an object whose contract routes through the converter while CanWrite has been overridden to true, or invoking WriteJson directly on the converter instance. Note the base CanWrite is false, so under normal serialization Newtonsoft skips WriteJson; hitting this means CanWrite was overridden or WriteJson was called manually.","commonSituations":"A developer overrides CanWrite => true on a CustomCreationConverter subclass thinking it will serialize polymorphically. Calling converter.WriteJson(...) directly in custom code. Confusing CustomCreationConverter (deserialize-only) with a full read/write converter.","solutions":["Do not serialize through a CustomCreationConverter; remove the CanWrite override that re-enabled writing, or switch to a full JsonConverter that implements both directions.","Use a different converter base (plain JsonConverter) if you need custom serialization too.","If you only need custom deserialization, keep CanWrite = false and rely on the default serializer for writing."],"exampleFix":"// before: re-enabling write on a deserialize-only converter\npublic class FooConverter : CustomCreationConverter<IFoo>\n{\n    public override bool CanWrite => true; // triggers NotSupportedException\n    public override IFoo Create(Type t) => new Foo();\n}\n\n// after: keep it read-only; use a separate converter for writing\npublic class FooConverter : CustomCreationConverter<IFoo>\n{\n    public override IFoo Create(Type t) => new Foo();\n    // CanWrite stays false (default)\n}","handlingStrategy":"validation","validationCode":"var conv = new MyCreationConverter();\nif (conv is CustomCreationConverter<IFoo> ccc && ccc.CanWrite)\n    throw new InvalidOperationException(\"CustomCreationConverter must not be used for writing; keep CanWrite=false\");","typeGuard":"static bool IsWriteSafeConverter(JsonConverter c) =>\n    !(c is CustomCreationConverter<IFoo> cc && cc.CanWrite);","tryCatchPattern":"try { serializer.Serialize(writer, obj); }\ncatch (NotSupportedException ex) when (ex.Message.Contains(\"only be used while deserializing\"))\n{\n    throw new InvalidOperationException(\"A deserialize-only converter was used for serialization\", ex);\n}","preventionTips":["Keep CanWrite = false on CustomCreationConverter subclasses.","Use a full JsonConverter if you need custom serialization in both directions.","Do not call WriteJson directly on deserialize-only converters."],"tags":["serialization","converter","not-supported","custom-creation"],"analyzedSha":"4f73e74372445108d2c1bda37b36e6f5e43402e0","analyzedAt":"2026-08-07T06:10:08.596Z","schemaVersion":2},"datasetVersion":"2026-08-07T07:17:06.508Z"}