JamesNK/Newtonsoft.Json · error · JsonSerializationException

Expected Version object value

Error message

Expected Version object value

What it means

Thrown by VersionConverter.WriteJson when the value is not null and not a System.Version. The converter writes the Version as its string representation; any other non-null runtime type reaches the else branch and throws this JsonSerializationException.

Source

Thrown at Src/Newtonsoft.Json/Converters/VersionConverter.cs:55

        /// <summary>
        /// Writes the JSON representation of the object.
        /// </summary>
        /// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
        /// <param name="value">The value.</param>
        /// <param name="serializer">The calling serializer.</param>
        public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
        {
            if (value == null)
            {
                writer.WriteNull();
            }
            else if (value is Version)
            {
                writer.WriteValue(value.ToString());
            }
            else
            {
                throw new JsonSerializationException("Expected Version object value");
            }
        }

        /// <summary>
        /// Reads the JSON representation of the object.
        /// </summary>
        /// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
        /// <param name="objectType">Type of the object.</param>
        /// <param name="existingValue">The existing property value of the JSON that is being converted.</param>
        /// <param name="serializer">The calling serializer.</param>
        /// <returns>The object value.</returns>
        public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer)
        {
            if (reader.TokenType == JsonToken.Null)
            {
                return null;
            }
            else

View on GitHub (pinned to 4f73e74372)

Solutions

  1. Ensure the value is a System.Version (or null) before it reaches VersionConverter.
  2. Remove the VersionConverter attribute from properties whose type is no longer System.Version.
  3. For a custom SemVer type, implement a dedicated JsonConverter rather than reusing VersionConverter.

Example fix

// before: custom SemVer type with VersionConverter
[JsonConverter(typeof(VersionConverter))]
public SemanticVersion Version { get; set; }

// after: dedicated converter for the custom type
[JsonConverter(typeof(SemVerConverter))]
public SemanticVersion Version { get; set; }
Defensive patterns

Strategy: type-guard

Validate before calling

object value = GetValue();
if (value != null && !(value is Version))
    throw new InvalidOperationException($"VersionConverter cannot serialize {value.GetType()}");

Type guard

static bool IsVersion(object v) => v is Version;

Try / catch

try { conv.WriteJson(writer, value, serializer); }
catch (JsonSerializationException ex) when (ex.Message.Contains("Expected Version object"))
{
    throw new InvalidOperationException($"VersionConverter got {value?.GetType()}", ex);
}

Prevention

When it happens

Trigger: Applying VersionConverter to a property/type whose runtime value is not a System.Version (e.g. a custom Version-like struct, a string, or a SemVer class). A polymorphic value whose declared type is Version but whose runtime type differs.

Common situations: Refactoring a Version property into a custom SemanticVersion type but leaving the VersionConverter attribute. Forcing VersionConverter onto a string-typed property via a contract resolver. Polymorphic serialization where the actual instance is not a Version.

Related errors


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