-
Notifications
You must be signed in to change notification settings - Fork 5.2k
Closed
Labels
Description
Description
Calling GetPath
on a JsonObject
child node in parallel triggers InvalidOperationException.
Reproduction Steps
var tree = (JsonNode.Parse(
"""
{
"oh": "noes"
}
"""
) as JsonObject)!;
// Workaround, do this once before parallel
// tree.First().Value!.GetPath();
Parallel.ForEach(Enumerable.Range(0, 10), _ =>
{
tree.First().Value!.GetPath();
});
Expected behavior
I expect parallel reads from the JsonNode/Object/Values to be thread safe.
Actual behavior
On JsonObject.GetPath
, line string propertyName = FindValue(child)!.Value.Key;
I get the following exception + stack trace:
System.InvalidOperationException: Nullable object must have a value.
at System.Nullable`1.get_Value()
at System.Text.Json.Nodes.JsonObject.GetPath(ValueStringBuilder& path, JsonNode child)
at System.Text.Json.Nodes.JsonNode.GetPath()
...
Regression?
Possibly regression from #77421
Known Workarounds
Traverse the object hierarchy serially once before parallel access to force lazy-initialization.
Configuration
Using .net sdk 9.0.305.
I don't think the rest matters, but macOS 15.7.1, arm64.
Other information
I guess calling tree.First()
in the repro triggers initialization of the underlying Dictionary and I can't see anything in place to avoid a race condition there.
Copilot