microsoft/aspire · error · InvalidOperationException
Failed to get or create property
Error message
Failed to get or create property '{key}' What it means
This internal JsonExtensions.Prop helper guarantees that indexing a JsonObject by key always returns a non-null JsonNode: it reads the property, and if missing, adds a new empty JsonObject under that key. The InvalidOperationException is thrown only if TryAdd fails (the key was concurrently added or the node exists with a JSON null value) and the subsequent lookup still yields null. In practice this fires when the property exists but holds a JSON literal null rather than an object, so TryAdd cannot replace it and the stored null is returned.
Solutions
- Inspect the JSON document being navigated: replace any explicit JSON null for the failing key with an object ({}), or remove the property.
- Guard traversal with jsonObj.ContainsKey/key checks or [key] is JsonObject checks before calling Prop for keys that may be null.
- Avoid sharing a mutable JsonObject across concurrent tasks; build JSON trees single-threaded or under a lock.
- If this appears without an obvious null in the input, treat it as an Aspire internal invariant break and report it with the JSON payload being processed.
Example fix
// before
var value = bicepJson.Prop("parameters").Prop("location");
// after
if (bicepJson["parameters"] is not JsonObject paramsObj)
{
throw new InvalidOperationException("'parameters' is missing or not an object (check for JSON null).");
}
var value = paramsObj.Prop("location"); Defensive patterns
Strategy: type-guard
Type guard
static bool TryProp(JsonNode? obj, string key, out JsonNode? node)
{
node = (obj as JsonObject)?[key];
return node is JsonObject; // false when the property is JSON null or missing
} Try / catch
try
{
var value = json.Prop("parameters").Prop(key);
}
catch (InvalidOperationException ex) when (ex.Message.StartsWith("Failed to get or create property"))
{
logger.LogWarning(ex, "JSON property was null or unexpectedly absent; skipping.");
} Prevention
- Never set JSON properties to explicit null in payloads that will be traversed with Prop().
- Use [key] is JsonObject checks before deep navigation of parsed JSON.
- Keep JsonObject mutation single-threaded or synchronized; don't share mutable JSON trees across tasks.
- Treat any occurrence of this exception as a bug report against Aspire — the helper is designed never to return null.
When it happens
Trigger: Calling Prop() on a JSON property whose stored value is JSON null: jsonObj[key] is not null-check-friendly here only when TryAdd fails — i.e. the key exists with a null JsonNode — so the fallback jsonObj[key] returns null and the exception fires. Also possible with concurrent mutation of the same JsonObject from multiple threads between the read and TryAdd.
Common situations: Parsing Bicep/ARM parameter files or deployment outputs where a nested property is explicitly set to null ("parameters": { "foo": null }); code traversing that shape with obj.Prop("foo").Prop("bar") hits the null node. Concurrent JSON mutation from parallel tasks sharing one JsonObject.
Understand the failure class
Background: JSON parse error: "Unexpected token" / "not valid JSON" / "failed to parse" — what JSON parsers are really complaining about — this error's family across 45 libraries.
Related errors
- Expected a JSON array.
- Expected property name.
- Expected start of chat message object.
- Service should have valid address at this point
- Unexpected end of JSON while reading property value.
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/5d58ed57688a1f0b.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Azure/Provisioning/JsonExtensions.cs:29
{
var jsonObj = obj.AsObject();
// Try to get the existing node
var node = jsonObj[key];
if (node is not null)
{
return node;
}
// Create a new node and try to add it
node = new JsonObject();
if (!jsonObj.TryAdd(key, node))
{
node = jsonObj[key];
if (node is null)
{
throw new InvalidOperationException($"Failed to get or create property '{key}'");
}
}
return node;
}
}
View on GitHub (pinned to 25830f84bd)