JamesNK/Newtonsoft.Json · error · JsonSerializationException

Expected date object value.

Error message

Expected date object value.

What it means

Thrown by UnixDateTimeConverter.WriteJson when the value is not a DateTime or DateTimeOffset. This converter emits dates as Unix epoch seconds; only DateTime and DateTimeOffset are accepted (the DateTimeOffset branch requires HAVE_DATE_TIME_OFFSET), so any other runtime type triggers the error.

Source

Thrown at Src/Newtonsoft.Json/Converters/UnixDateTimeConverter.cs:92

        /// <param name="value">The value.</param>
        /// <param name="serializer">The calling serializer.</param>
        public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer)
        {
            long seconds;

            if (value is DateTime dateTime)
            {
                seconds = (long)(dateTime.ToUniversalTime() - UnixEpoch).TotalSeconds;
            }
#if HAVE_DATE_TIME_OFFSET
            else if (value is DateTimeOffset dateTimeOffset)
            {
                seconds = (long)(dateTimeOffset.ToUniversalTime() - UnixEpoch).TotalSeconds;
            }
#endif
            else
            {
                throw new JsonSerializationException("Expected date object value.");
            }

            if (!AllowPreEpoch && seconds < 0)
            {
                throw new JsonSerializationException("Cannot convert date value that is before Unix epoch of 00:00:00 UTC on 1 January 1970.");
            }

            writer.WriteValue(seconds);
        }

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

View on GitHub (pinned to 4f73e74372)

Solutions

  1. Ensure the value is DateTime or DateTimeOffset before it reaches UnixDateTimeConverter.
  2. Remove the converter attribute from properties that are no longer dates.
  3. If the value is already epoch seconds, serialize it as a plain long without this converter.

Example fix

// before: value is already epoch seconds, converter double-converts
[JsonConverter(typeof(UnixDateTimeConverter))]
public long EpochSeconds { get; set; }

// after: serialize raw long, no date converter
public long EpochSeconds { 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($"UnixDateTimeConverter 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($"UnixDateTimeConverter got {value?.GetType()}", ex);
}

Prevention

When it happens

Trigger: Applying UnixDateTimeConverter to a property/type whose runtime value is not DateTime or DateTimeOffset. On platforms without DateTimeOffset support, passing a DateTimeOffset also fails.

Common situations: A property refactored from DateTime to int/long (epoch already) or string while UnixDateTimeConverter is still attached. Serializing DateOnly/TimeOnly. Cross-platform builds where DateTimeOffset is compiled out.

Related errors


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