JsonException: The JSON object contains a trailing comma at the end which is not
supported in this mode. Change the reader options. means the JSON has a comma after
the last property of an object, and the default System.Text.Json options refuse it. Remove
the comma from the JSON, or set AllowTrailingCommas = true on
JsonSerializerOptions.
"Change the reader options" points at that property. Setting it on the options passed to
Deserialize made the same JSON load in the reproduction below.
The error
Unhandled exception. System.Text.Json.JsonException: The JSON object contains a trailing comma at the end which is not supported in this mode. Change the reader options. Path: $ | LineNumber: 3 | BytePositionInLine: 0.
---> System.Text.Json.JsonReaderException: The JSON object contains a trailing comma at the end which is not supported in this mode. Change the reader options. LineNumber: 3 | BytePositionInLine: 0.
at System.Text.Json.ThrowHelper.ThrowJsonReaderException(Utf8JsonReader& json, ExceptionResource resource, Byte nextByte, ReadOnlySpan`1 bytes)
...
at System.Text.Json.JsonSerializer.Deserialize[TValue](String json, JsonSerializerOptions options)
at Program.<Main>$(String[] args) in C:\...\tc\Program.cs:line 18
Why it happens
The JSON in the test was this, a hand-edited object where the comma after the last property was left in place:
{
"Name": "Aiko Tanaka",
"City": "Lisbon",
}
The inner exception is a JsonReaderException: the failure comes from the
reader, before any property is mapped to the class, which is why the message talks about
reader options rather than about the Customer type. The position is the
useful part. LineNumber: 3 | BytePositionInLine: 0 counts lines from zero, so
line 3 is the fourth line, the closing brace that follows the comma.
The outer JsonException adds Path: $, the root object, since the
comma sits directly inside it. The stack trace shows
Utf8JsonReader.ConsumeNextTokenOrRollback and
Utf8JsonReader.Read() under the converter that was reading the object, which
matches the reader being the part that stopped.
The fix
var options = new JsonSerializerOptions { AllowTrailingCommas = true };
var fixedCustomer = JsonSerializer.Deserialize<Customer>(json, options)!;
Console.WriteLine($"{fixedCustomer.Name}, {fixedCustomer.City}");
Running dotnet run -- fix with the same JSON printed:
Aiko Tanaka, Lisbon
Both properties were read. If the JSON comes from a file you control, deleting the comma
after "Lisbon" is the smaller change and needs no code change. Use AllowTrailingCommas when the JSON is written by people,
for example a settings file, and you would rather accept the comma than fail.
How it was reproduced
A console project from dotnet new console on .NET SDK 10.0.403
(net10.0, no extra packages; System.Text.Json is part of the framework), a
Customer class with two string properties and
JsonSerializer.Deserialize<Customer>(json) with default options on the
JSON above. Run with dotnet run for the error and
dotnet run -- fix for the options with AllowTrailingCommas.
Frequently asked
- How do I allow trailing commas in System.Text.Json?
- Create the options with new JsonSerializerOptions { AllowTrailingCommas = true } and pass them to JsonSerializer.Deserialize. In the test the JSON with a comma after the last property then loaded.
- What does Change the reader options mean?
- The comma was rejected by the JSON reader, under the default options. AllowTrailingCommas on JsonSerializerOptions is the reader setting that accepts it.
- Which line has the trailing comma?
- The exception gives LineNumber and BytePositionInLine counted from zero. In the test LineNumber 3 pointed at the fourth line, the closing brace right after the comma.
More decoded errors in the Fixes category, where the other System.Text.Json posts sit in the EF Core, SQL Server and PostgreSQL group.