OrchardCMS/OrchardCore · error · JsonException
Unknown token type
Error message
Unknown token type {0} What it means
This is the terminal fallback of DynamicJsonConverter.Read: after the switch exhausts all recognized JsonTokenType cases it throws a JsonException formatted with the unknown reader.TokenType. Unlike error 45 (thrown inside object parsing), this fires at the top-level dispatch, meaning the very first/most recent token read was of a type the converter never mapped at all. It signals the converter was handed JSON it was never designed to consume.
Solutions
- Check reader.TokenType before calling the deserializer; call reader.Read() at least once so TokenType is not None.
- Strip comments or avoid JsonCommentHandling.Allow when the payload goes through this converter.
- Ensure the stream/reader is rewound (reader = new Utf8JsonReader(buffer)) and not already exhausted before deserialization.
- Deserialize the complete top-level value (object/array), not a fragment; wrap primitives in a document if needed.
- If a new token type is valid for your data, add an explicit case for it in DynamicJsonConverter.Read.
Example fix
// before: unadvanced reader
var reader = new Utf8JsonReader(buffer);
var value = JsonSerializer.Deserialize<JsonDynamicObject>(ref reader);
// after: advance the reader to a real token first
var reader = new Utf8JsonReader(buffer);
if (!reader.Read()) throw new InvalidDataException("Empty payload");
if (reader.TokenType == JsonTokenType.StartObject)
{
var value = JsonSerializer.Deserialize<JsonDynamicObject>(ref reader);
} Defensive patterns
Strategy: validation
Validate before calling
var reader = new Utf8JsonReader(buffer);
if (!reader.Read()) throw new InvalidDataException("Empty JSON payload");
if (reader.TokenType is JsonTokenType.None or JsonTokenType.Comment or JsonTokenType.PropertyName or JsonTokenType.EndObject or JsonTokenType.EndArray)
throw new InvalidDataException($"Reader must start on a value token, got {reader.TokenType}"); Type guard
static bool IsValueStartToken(JsonTokenType t) =>
t is JsonTokenType.StartObject or JsonTokenType.StartArray
or JsonTokenType.String or JsonTokenType.Number
or JsonTokenType.True or JsonTokenType.False or JsonTokenType.Null; Try / catch
try
{
var value = JsonSerializer.Deserialize<JsonDynamicObject>(ref reader, options);
}
catch (JsonException ex) when (ex.Message.StartsWith("Unknown token type"))
{
logger.LogError(ex, "Reader was on token {Token}; rewind the reader to a value start", reader.TokenType);
reader = new Utf8JsonReader(buffer); reader.Read(); // rewind and retry once
} Prevention
- Call reader.Read() before deserializing so TokenType is never None.
- Do not enable JsonCommentHandling.Allow for payloads handled by this converter.
- Deserialize whole top-level values, never JSON fragments or trailing end tokens.
- Keep a single serializer options instance so converter routing is predictable.
- Test with empty, truncated, and comment-laden payloads.
When it happens
Trigger: JsonSerializer.Deserialize/Serialize with a type routed through DynamicJsonConverter when reader.TokenType is outside the handled set — e.g. None (reader not advanced), a stray PropertyName, EndObject/EndArray reached as a value position, or a comment token (JsonCommentHandling.Allow).
Common situations: Passing an unadvanced Utf8JsonReader (TokenType == None) into deserialization; enabling comment handling and feeding JSON with comments; calling Deserialize on a stream already consumed; custom pipeline code that re-reads a value and hands the converter an EndObject token.
Understand the failure class
Background: "failed to unmarshal" / json.Unmarshal errors: why parsing a response into a Go struct fails and how to fix it — this error's family across 23 libraries.
Related errors
- Deserializing a is not supported.
- Unexpected token type
- Unexpected token parsing TimeSpan. Expected a string, got
- Unable to convert ' ' to TimeSpan.
- Cannot convert to
AI-assisted analysis of OrchardCMS/OrchardCore@4306c0717f (2026-09-13).
Data as JSON: /api/errors/d5562863079c15d7.
Report an issue: GitHub.
Appendix: source
Thrown at src/OrchardCore/OrchardCore.Abstractions/Json/Serialization/DynamicJsonConverter.cs:93
case JsonTokenType.PropertyName:
var key = reader.GetString();
reader.Read();
if (key is not null)
{
dictionary[key] = Read(ref reader, typeof(object), options);
}
break;
default:
throw new JsonException("Cannot parse object.");
}
}
throw new JsonException();
default:
throw new JsonException(string.Format("Unknown token type {0}", reader.TokenType));
}
}
public override void Write(
Utf8JsonWriter writer,
object objectToWrite,
JsonSerializerOptions options) =>
JsonSerializer.Serialize(writer, objectToWrite, objectToWrite.GetType(), options);
}
View on GitHub (pinned to 4306c0717f)