{"record":{"id":"e56ea685324c15cd","repo":"microsoft/aspire","slug":"json-patch-operation-operation-requires-a-value-property","errorCode":null,"errorMessage":"JSON Patch operation '{operation}' requires a 'value' property.","messagePattern":"JSON Patch operation '(.+?)' requires a 'value' property\\.","errorType":"exception","errorClass":"JsonException","httpStatus":null,"severity":"error","filePath":"src/Aspire.Hosting/Dcp/JsonPatch.cs","lineNumber":188,"sourceCode":"                '0' => '~',\n                '1' => '/',\n                _ => throw new JsonException($\"JSON Pointer segment '{segment}' contains an invalid escape.\"),\n            });\n        }\n\n        return result.ToString();\n    }\n\n    private static JsonNode? ApplyOperation(JsonNode? current, string operation, string[] segments, bool hasValue, JsonNode? value)\n    {\n        if (operation is not (\"add\" or \"remove\" or \"replace\"))\n        {\n            throw new JsonException($\"JSON Patch operation '{operation}' is not supported.\");\n        }\n\n        if (operation is not \"remove\" && !hasValue)\n        {\n            throw new JsonException($\"JSON Patch operation '{operation}' requires a 'value' property.\");\n        }\n\n        if (segments.Length == 0)\n        {\n            return operation switch\n            {\n                \"remove\" => null,\n                _ => value?.DeepClone(),\n            };\n        }\n\n        var parent = GetParent(current, segments);\n        var finalSegment = segments[^1];\n\n        switch (parent)\n        {\n            case JsonObject jsonObject:\n                ApplyToObject(jsonObject, operation, finalSegment, value);","sourceCodeStart":170,"sourceCodeEnd":206,"githubUrl":"https://github.com/microsoft/aspire/blob/25830f84bd145686607ad00c057b3f84e2e51d43/src/Aspire.Hosting/Dcp/JsonPatch.cs#L170-L206","documentation":"For 'add' and 'replace' JSON Patch operations, RFC 6902 requires a 'value' property. ApplyOperation throws a JsonException when an operation other than 'remove' is applied without a value, since there is nothing to insert or substitute.","triggerScenarios":"Applying { \"op\": \"add\", \"path\": \"/spec/env/KEY\" } with no \"value\" member, or a 'replace' whose value was dropped during serialization, via the DCP resource update path.","commonSituations":"Patch producers that omit 'value' when it is null (serializers with IgnoreNullValues dropping JsonValue null); hand-written patches forgetting the value; schema drift between producer and consumer.","solutions":["Always include a \"value\" property in 'add' and 'replace' operations, using \"value\": null explicitly if null is intended.","Configure the patch serializer to not drop null values (e.g. DefaultIgnoreCondition = Never for patch docs).","Use 'remove' instead of 'replace' with an absent value when deletion is the intent.","Validate patch documents before applying them to catch missing 'value' early."],"exampleFix":"// before\n[ { \"op\": \"replace\", \"path\": \"/spec/replicas\" } ]\n// after\n[ { \"op\": \"replace\", \"path\": \"/spec/replicas\", \"value\": 3 } ]","handlingStrategy":"validation","validationCode":"bool HasRequiredValues(JsonNode patch) =>\n    patch.AsArray().All(op =>\n    {\n        var name = op[\"op\"]!.GetValue<string>();\n        return name == \"remove\" || op.AsObject().ContainsKey(\"value\");\n    });","typeGuard":null,"tryCatchPattern":"try { patch.Apply(target); }\ncatch (JsonException ex) when (ex.Message.Contains(\"requires a 'value' property\"))\n{\n    logger.LogError(ex, \"Patch op missing 'value': {Message}\", ex.Message);\n}","preventionTips":["Always serialize \"value\": null explicitly instead of dropping null members.","Use 'remove' rather than value-less 'replace' for deletions.","Configure JsonSerializerOptions with DefaultIgnoreCondition = Never for patch documents."],"tags":["json-patch","rfc6902","missing-value","dcp"],"backgroundTag":"missing-required-argument","analyzedSha":"25830f84bd145686607ad00c057b3f84e2e51d43","analyzedAt":"2026-09-16T11:10:06.193Z","contentChangedAt":"2026-09-16T11:10:06.193Z","schemaVersion":2},"datasetVersion":"2026-09-21T09:17:21.228Z"}