microsoft/aspire · error · JsonException

JSON Patch remove path refers to missing property

Error message

JSON Patch remove path refers to missing property '{propertyName}'.

What it means

ApplyToObject implements the 'remove' operation for JsonObject targets. RFC 6902 requires that 'remove' only targets an existing member, so when the property is absent the library throws this JsonException instead of silently succeeding. This surfaces bugs in patch composition rather than masking them.

Solutions

  1. Check the property exists (target.ContainsKey) or catch the JsonException and treat it as a no-op if removal is optional
  2. Use a 'replace'/'add' with null or an empty value instead of remove when the property may not exist
  3. Fix the path to the correct property name

Example fix

// before
new JsonPatchOperation("remove", "/metadata/annotations/debug") // may not exist
// after
if (((JsonObject)doc.Root["metadata"]!["annotations"]!).ContainsKey("debug"))
    new JsonPatchOperation("remove", "/metadata/annotations/debug");
Defensive patterns

Strategy: validation

Validate before calling

static bool CanRemove(JsonObject target, string propertyName) => target.ContainsKey(propertyName);

Try / catch

try { patcher.Apply(doc, operations); }
catch (JsonException ex) when (ex.Message.Contains("remove path refers to missing property")) {
    logger.LogDebug(ex, "Property already absent; treating remove as no-op");
}

Prevention

When it happens

Trigger: Applying a remove operation with path '/annotations/foo' when the 'annotations' object has no 'foo' property (or 'annotations' resolution itself succeeded but the key is absent).

Common situations: Removing an annotation/label that was never set; idempotency mistakes when replaying patches; removing properties after a schema rename.

Understand the failure class

Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.

Related errors


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

Appendix: source

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

                    ?? 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)
    {
        switch (operation)
        {
            case "add":
                target[propertyName] = value?.DeepClone();
                break;
            case "remove":
                if (!target.Remove(propertyName))
                {
                    throw new JsonException($"JSON Patch remove path refers to missing property '{propertyName}'.");
                }
                break;
            case "replace":
                if (!target.ContainsKey(propertyName))
                {
                    throw new JsonException($"JSON Patch replace path refers to missing property '{propertyName}'.");
                }
                target[propertyName] = value?.DeepClone();
                break;
        }
    }

    private static void ApplyToArray(JsonArray target, string operation, string indexText, JsonNode? value)
    {
        if (operation == "add" && indexText == "-")
        {
            target.Add(value?.DeepClone());
            return;

View on GitHub (pinned to 25830f84bd)