microsoft/aspire · error · JsonException
A JSON Patch operation must contain string 'op' and 'path'…
Error message
A JSON Patch operation must contain string 'op' and 'path' properties.
What it means
JsonPatch.Apply parses each operation of a JSON Patch document and requires every operation to be a JSON object with string-valued 'op' and 'path' properties per RFC 6902. If an operation is not an object, or 'op'/'path' are missing or not strings, a JsonException is thrown to abort application of the patch.
Solutions
- Ensure every patch operation is a JSON object containing both "op" (string) and "path" (string).
- Validate the patch document against RFC 6902 before applying it.
- Check the producer of the patch (custom resource update code) for typos in property names.
- Log the raw patch JSON to identify which operation index is malformed.
Example fix
// before
[ { "operation": "replace", "path": "/spec/replicas", "value": 3 } ]
// after
[ { "op": "replace", "path": "/spec/replicas", "value": 3 } ] Defensive patterns
Strategy: validation
Validate before calling
bool IsValidOperation(JsonNode node) =>
node is JsonObject o &&
o["op"] is JsonValue ov && ov.TryGetValue<string>(out _) &&
o["path"] is JsonValue pv && pv.TryGetValue<string>(out _); Type guard
bool IsStringProperty(JsonObject o, string name) => o[name] is JsonValue v && v.TryGetValue<string>(out _);
Try / catch
try { patch.Apply(target); }
catch (JsonException ex)
{
logger.LogError(ex, "Malformed JSON Patch document: {Message}", ex.Message);
} Prevention
- Validate the patch document against RFC 6902 before applying.
- Always emit string 'op' and 'path' in every operation.
- Log the raw patch JSON when application fails to spot malformed ops.
When it happens
Trigger: Applying a patch document whose operation lacks 'op' or 'path', or where these are non-string (e.g. "op": 1, or a shorthand form); patch JSON deserialized from an untrusted/incorrect source via ApplyUpdate on a DCP resource snapshot.
Common situations: Hand-written patch JSON with typos ('operation' instead of 'op'); producers emitting numeric op codes; schema drift between the patch producer and Aspire.Hosting's parser.
Understand the failure class
Background: Schema validation failed / invalid input schema: payload rejected because its shape doesn't match the expected schema — this error's family across 28 libraries.
Related errors
- JSON Patch operation
- JSON Patch operation
- A JSON Patch path can only traverse objects and arrays.
- A JSON Patch path cannot traverse a null value.
- All resources should be of the same kind when calling…
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/81ca5f00d7e9c2cd.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting/Dcp/JsonPatch.cs:37
var operations = new JsonArray();
AddOperations(current, changed, string.Empty, operations);
return operations;
}
internal static JsonNode? Apply(JsonNode? current, JsonArray patch)
{
var result = current?.DeepClone();
foreach (var operationNode in patch)
{
if (operationNode is not JsonObject operation ||
operation["op"] is not JsonValue operationValue ||
operation["path"] is not JsonValue pathValue ||
!operationValue.TryGetValue<string>(out var operationName) ||
!pathValue.TryGetValue<string>(out var path))
{
throw new JsonException("A JSON Patch operation must contain string 'op' and 'path' properties.");
}
var segments = ParsePath(path);
var hasValue = operation.TryGetPropertyValue("value", out var value);
result = ApplyOperation(result, operationName, segments, hasValue, value);
}
return result;
}
private static void AddOperations(JsonNode? current, JsonNode? changed, string path, JsonArray operations)
{
if (JsonNode.DeepEquals(current, changed))
{
return;
}
if (current is JsonObject currentObject && changed is JsonObject changedObject)View on GitHub (pinned to 25830f84bd)