Skip to content

Fix GetValue<object>() on JsonValueOfJsonPrimitive types#125139

Draft
Copilot wants to merge 2 commits intomainfrom
copilot/fix-breaking-change-jsonnodeconverter
Draft

Fix GetValue<object>() on JsonValueOfJsonPrimitive types#125139
Copilot wants to merge 2 commits intomainfrom
copilot/fix-breaking-change-jsonnodeconverter

Conversation

Copy link
Contributor

Copilot AI commented Mar 3, 2026

Description

JsonValueOfJsonString, JsonValueOfJsonBool, and JsonValueOfJsonNumber (introduced in .NET 10) throw InvalidOperationException on GetValue<object>() because their TryGetValue<T> methods don't handle typeof(T) == typeof(object). The older JsonValueOfElement handled this implicitly via if (Value is TypeToConvert element).

var reader = new Utf8JsonReader("\"Hello World!\""u8);
reader.Read();
var node = converter.Read(ref reader, typeof(JsonNode), options);

// .NET 10: throws InvalidOperationException
// .NET 9:  works fine
var o = node.GetValue<object>();

Changes

  • JsonValueOfJsonString: Added typeof(T) == typeof(object) to the string branch — returns the decoded string
  • JsonValueOfJsonBool: Added typeof(T) == typeof(object) to the bool branch — returns the boxed bool
  • JsonValueOfJsonNumber: Added typeof(T) == typeof(object) to the JsonElement branch — returns a JsonElement (no single numeric type to pick; consistent with prior JsonValueOfElement behavior)
  • Added TryGetValue<object> assertions to existing tests and a new GetValue_Object theory exercising the converter code path
Original prompt

This section details on the original issue you should resolve

<issue_title>Breaking change in JsonNodeConverter</issue_title>
<issue_description>### Description

Using a JsonConverter to read a string node, .NET 9 and .NET 10 show different behavior.

The new System.Text.Json.Nodes.JsonValueOfJsonString introduced in .NET 10 cannot be converted to an object using GetValue<object>(), resulting in an exception.

Reproduction Steps

See Repo at https://github.com/NiceWaffel/jsonnodeconverter-repro

var reader = new Utf8JsonReader("\"Hello World!\""u8);
reader.Read();
var node = (SerializationContext.Default.JsonNode.Converter as JsonConverter<JsonNode>)
  ?.Read(ref reader, typeof(JsonNode), SerializationContext.Default.Options);

Debug.Assert(node != null, "We should get a valid JsonNode.");

// Different type in .NET 8, .NET 9 and .NET 10
// .NET 8: System.Text.Json.Nodes.JsonValuePrimitive`1[System.Text.Json.JsonElement]
// .NET 9: System.Text.Json.Nodes.JsonValueOfElement
// .NET 10: System.Text.Json.Nodes.JsonValueOfJsonString
Console.WriteLine(node.GetType());

// Exception in .NET 10 (no exception in .NET 8)
// System.InvalidOperationException: An element of type 'String' cannot be converted to a 'System.Object'.
var o = node.GetValue<object>();
Console.WriteLine(o);

Expected behavior

The behavior in .NET 8, .NET 9 and .Net 10 should be the same. No exception should be thrown.

Actual behavior

In .NET 10, a string JsonNode (read as JsonValueOfJsonString) cannot be converted to an object, resulting in an exception.

Unhandled exception. System.InvalidOperationException: An element of type 'String' cannot be converted to a 'System.Object'.
   at System.Text.Json.ThrowHelper.ThrowInvalidOperationException_NodeUnableToConvertElement(JsonValueKind valueKind, Type destinationType)
   at System.Text.Json.Nodes.JsonValueOfJsonString.GetValue[T]()

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

JsonValueOfJsonString was introduced with #116798</issue_description>

Comments on the Issue (you are @copilot in this section)


🔒 GitHub Advanced Security automatically protects Copilot coding agent pull requests. You can protect all pull requests by enabling Advanced Security for your repositories. Learn more about Advanced Security.

@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @dotnet/area-system-text-json
See info in area-owners.md if you want to be subscribed.

Handle typeof(T) == typeof(object) in TryGetValue for
JsonValueOfJsonString, JsonValueOfJsonBool, and JsonValueOfJsonNumber.
This fixes InvalidOperationException when calling GetValue<object>()
on these types that were introduced in .NET 10.

Co-authored-by: eiriktsarpalis <2813363+eiriktsarpalis@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Breaking change in JsonNodeConverter

3 participants