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;
}
elseView on GitHub (pinned to 4f73e74372)
Solutions
- Ensure the value is a System.Version (or null) before it reaches VersionConverter.
- Remove the VersionConverter attribute from properties whose type is no longer System.Version.
- 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
- Only attach VersionConverter to System.Version members.
- For custom SemVer types, write a dedicated converter.
- Re-audit converter attributes after refactoring.
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
- Unexpected value type when writing binary: {0}
- Unexpected value when converting date. Expected DateTime or
- Expected date object value.
- Expected date object value.
- Value must be an XML object.
AI-assisted analysis of JamesNK/Newtonsoft.Json@4f73e74372 (2026-08-07).
Data as JSON: /api/errors/475b18a051ea4618.
Report an issue: GitHub.