{"record":{"id":"d01e13925f3bab36","repo":"microsoft/aspire","slug":"a-json-patch-path-cannot-traverse-a-null-value","errorCode":null,"errorMessage":"A JSON Patch path cannot traverse a null value.","messagePattern":"A JSON Patch path cannot traverse a null value\\.","errorType":"exception","errorClass":"JsonException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/Dcp/JsonPatch.cs","lineNumber":220,"sourceCode":"\n        switch (parent)\n        {\n            case JsonObject jsonObject:\n                ApplyToObject(jsonObject, operation, finalSegment, value);\n                break;\n            case JsonArray jsonArray:\n                ApplyToArray(jsonArray, operation, finalSegment, value);\n                break;\n            default:\n                throw new JsonException(\"A JSON Patch path can only traverse objects and arrays.\");\n        }\n\n        return current;\n    }\n\n    private static JsonNode GetParent(JsonNode? current, string[] segments)\n    {\n        var parent = current ?? throw new JsonException(\"A JSON Patch path cannot traverse a null value.\");\n\n        for (var index = 0; index < segments.Length - 1; index++)\n        {\n            var segment = segments[index];\n            parent = parent switch\n            {\n                JsonObject jsonObject when jsonObject.TryGetPropertyValue(segment, out var child) && child is not null => child,\n                JsonArray jsonArray => jsonArray[ParseArrayIndex(segment, jsonArray.Count, allowEnd: false)]\n                    ?? throw new JsonException($\"JSON Patch path segment '{segment}' refers to a null value.\"),\n                _ => throw new JsonException($\"JSON Patch path segment '{segment}' does not exist.\"),\n            };\n        }\n\n        return parent;\n    }\n\n    private static void ApplyToObject(JsonObject target, string operation, string propertyName, JsonNode? value)\n    {","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/Dcp/JsonPatch.cs#L202-L238","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ensure the target document is non-null and fully materialized before calling Apply","Add the missing subtree with an 'add' operation before operations that descend into it","Check intermediate properties for JSON null (JsonValue kind Null) and rebuild them first"],"exampleFix":"// before\npatcher.Apply(null, operations); // current node is null\n// after\nif (resource.JsonValue is not null) patcher.Apply(resource.JsonValue, operations);","handlingStrategy":"type-guard","validationCode":"if (document is null || document.Root is null) throw new InvalidOperationException(\"Cannot patch a null document\");","typeGuard":"bool CanApply(JsonNode? node) => node is not null;","tryCatchPattern":"try { patcher.Apply(doc, operations); }\ncatch (JsonException ex) when (ex.Message.Contains(\"cannot traverse a null value\")) {\n    logger.LogWarning(ex, \"Patch target or intermediate node was null\");\n}","preventionTips":["Never call Apply before the resource document is materialized","Avoid explicitly setting properties to JSON null when patches will descend into them","Guard Apply calls with a null check on the root node"],"tags":["json-patch","null-reference","json"],"backgroundTag":"null-argument","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T04:17:39.646Z"}