JamesNK/Newtonsoft.Json · error · JsonSerializationException

Expected date object value.

Error message

Expected date object value.

What it means

Thrown by JavaScriptDateTimeConverter.WriteJson when the value is not a DateTime or DateTimeOffset. This converter serializes dates as a JavaScript Date constructor call (new Date(ticks)); only DateTime and DateTimeOffset are accepted, so any other type hits the else branch.

Source

Thrown at Src/Newtonsoft.Json/Converters/JavaScriptDateTimeConverter.cs:61

        public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
        {
            long ticks;

            if (value is DateTime dateTime)
            {
                DateTime utcDateTime = dateTime.ToUniversalTime();
                ticks = DateTimeUtils.ConvertDateTimeToJavaScriptTicks(utcDateTime);
            }
#if HAVE_DATE_TIME_OFFSET
            else if (value is DateTimeOffset dateTimeOffset)
            {
                DateTimeOffset utcDateTimeOffset = dateTimeOffset.ToUniversalTime();
                ticks = DateTimeUtils.ConvertDateTimeToJavaScriptTicks(utcDateTimeOffset.UtcDateTime);
            }
#endif
            else
            {
                throw new JsonSerializationException("Expected date object value.");
            }

            writer.WriteStartConstructor("Date");
            writer.WriteValue(ticks);
            writer.WriteEndConstructor();
        }

        /// <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)

View on GitHub (pinned to 4f73e74372)

Solutions

  1. Ensure only DateTime or DateTimeOffset values reach JavaScriptDateTimeConverter.
  2. Remove or replace the converter on properties whose type changed.
  3. For non-DateTime types, write a custom converter that converts to DateTime first.

Example fix

// before: property changed type, converter left in place
[JsonConverter(typeof(JavaScriptDateTimeConverter))]
public long TimestampMs { get; set; }

// after: remove converter from non-date type
[JsonProperty("timestampMs")]
public long TimestampMs { get; set; }
Defensive patterns

Strategy: type-guard

Validate before calling

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

Type guard

static bool IsDateType(object v) =>
    v is DateTime || v is DateTimeOffset;

Try / catch

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

Prevention

When it happens

Trigger: Applying JavaScriptDateTimeConverter to a property whose runtime value is not DateTime/DateTimeOffset. On builds without DateTimeOffset support, passing a DateTimeOffset also fails. Passing a nullable DateTime whose Value was boxed as something else.

Common situations: Switching a property type from DateTime to string/int but keeping the JavaScriptDateTimeConverter attribute. Serializing DateOnly/TimeOnly with this converter. Polymorphic values whose runtime type differs from the declared type.

Related errors


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