microsoft/aspire · error · JsonException

A JSON Patch path cannot traverse a null value.

Error message

A JSON Patch path cannot traverse a null value.

What it means

JsonPatch.GetParent walks the segments of a patch path to locate the parent node that an operation targets. If the starting node (or a node reached during traversal) is null, there is nothing to traverse and a JsonException is thrown. This guards against applying patches to absent subtrees.

Solutions

  1. Ensure the target document is non-null and fully materialized before calling Apply
  2. Add the missing subtree with an 'add' operation before operations that descend into it
  3. Check intermediate properties for JSON null (JsonValue kind Null) and rebuild them first

Example fix

// before
patcher.Apply(null, operations); // current node is null
// after
if (resource.JsonValue is not null) patcher.Apply(resource.JsonValue, operations);
Defensive patterns

Strategy: type-guard

Validate before calling

if (document is null || document.Root is null) throw new InvalidOperationException("Cannot patch a null document");

Type guard

bool CanApply(JsonNode? node) => node is not null;

Try / catch

try { patcher.Apply(doc, operations); }
catch (JsonException ex) when (ex.Message.Contains("cannot traverse a null value")) {
    logger.LogWarning(ex, "Patch target or intermediate node was null");
}

Prevention

When it happens

Trigger: Applying a patch to a document (or subtree) that is null — e.g. Apply called with a null current node, or a path whose earlier segment resolved to a JSON null.

Common situations: Patching a resource before it has been materialized; a property that was explicitly set to JSON null earlier in the document; passing a deserialized-but-empty node to Apply.

Related errors


AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16). Data as JSON: /api/errors/d01e13925f3bab36. Report an issue: GitHub.

Appendix: source

Thrown at src/Aspire.Hosting/Dcp/JsonPatch.cs:220

        switch (parent)
        {
            case JsonObject jsonObject:
                ApplyToObject(jsonObject, operation, finalSegment, value);
                break;
            case JsonArray jsonArray:
                ApplyToArray(jsonArray, operation, finalSegment, value);
                break;
            default:
                throw new JsonException("A JSON Patch path can only traverse objects and arrays.");
        }

        return current;
    }

    private static JsonNode GetParent(JsonNode? current, string[] segments)
    {
        var parent = current ?? throw new JsonException("A JSON Patch path cannot traverse a null value.");

        for (var index = 0; index < segments.Length - 1; index++)
        {
            var segment = segments[index];
            parent = parent switch
            {
                JsonObject jsonObject when jsonObject.TryGetPropertyValue(segment, out var child) && child is not null => child,
                JsonArray jsonArray => jsonArray[ParseArrayIndex(segment, jsonArray.Count, allowEnd: false)]
                    ?? throw new JsonException($"JSON Patch path segment '{segment}' refers to a null value."),
                _ => throw new JsonException($"JSON Patch path segment '{segment}' does not exist."),
            };
        }

        return parent;
    }

    private static void ApplyToObject(JsonObject target, string operation, string propertyName, JsonNode? value)
    {

View on GitHub (pinned to 25830f84bd)