microsoft/aspire · error
The persisted scope is not a JSON object.
Error message
The persisted scope is not a JSON object.
What it means
Thrown while parsing the persisted 'Scope' value from the AKS deployment state: the stored value is not a JSON object (JsonNode.Parse returned a non-object or null). The scope must be a JSON object like {"resourceGroup":"shared-rg","subscription":"<guid>"} as written by BicepUtilities.SetScopeAsync.
Solutions
- Inspect the Scope value in the deployment state file and fix it to the JSON object shape {"resourceGroup":...,"subscription":...}
- Re-deploy the environment so BicepUtilities.SetScopeAsync rewrites the scope in the correct shape
- If a custom module writes Scope, ensure it stores a JSON-encoded object, not a raw string
- Delete stale state and redeploy from scratch
Example fix
// before (bad stored value)
// "Scope": "shared-rg/00000000-0000-0000-0000-000000000000"
// after (correct)
// "Scope": "{ \"resourceGroup\": \"shared-rg\", \"subscription\": \"00000000-0000-0000-0000-000000000000\" }" Defensive patterns
Strategy: validation
Validate before calling
var scopeJson = state.Data["Scope"];
using var doc = JsonDocument.Parse(scopeJson);
if (doc.RootElement.ValueKind != JsonValueKind.Object)
throw new InvalidOperationException("Scope must be a JSON object with resourceGroup/subscription."); Prevention
- Only let BicepUtilities.SetScopeAsync write the Scope value
- Validate state schema after migrations or tooling upgrades
When it happens
Trigger: GetAksCredentialsForDestroyAsync reads deploymentStateSection.Data["Scope"], calls JsonNode.Parse(...).AsObject(), and the parsed node is a string/number/array/null instead of an object.
Common situations: The Scope output in the deployment state was corrupted or replaced by a plain string; a custom template wrote the scope without JSON encoding; state was hand-edited or migrated from a different schema version.
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
- The Azure deployment state for AKS environment
- The Azure deployment state for AKS environment
- No Azure deployment state was found for AKS environment
- The Azure deployment state for AKS environment
- az aks get-credentials failed
AI-assisted analysis of microsoft/aspire@25830f84bd (2026-09-16).
Data as JSON: /api/errors/e794c97309fa6aa7.
Report an issue: GitHub.
Appendix: source
Thrown at src/Aspire.Hosting.Azure.Kubernetes/AzureKubernetesEnvironmentResource.AksPipeline.cs:420
// Scope is persisted as a JSON string using the same shape produced by
// BicepUtilities.SetScopeAsync:
// { "resourceGroup": "shared-rg", "subscription": "00000000-..." }
// A missing property means the resource did not pin that scope value, so only that value
// falls back to global Azure deployment state. Older state without Scope uses the persisted
// resource ID so a changed AppHost scope cannot redirect cleanup to another cluster or wait
// on provisioning that is not part of the destroy graph.
string subscriptionId;
string? resourceGroupName;
if (deploymentStateSection.Data["Scope"] is not null)
{
string? scopedSubscription;
string? scopedResourceGroup;
try
{
var scopeJson = deploymentStateSection.Data["Scope"]!.GetValue<string>();
var scope = JsonNode.Parse(scopeJson)?.AsObject()
?? throw new InvalidOperationException("The persisted scope is not a JSON object.");
scopedSubscription = scope["subscription"]?.GetValue<string>();
scopedResourceGroup = scope["resourceGroup"]?.GetValue<string>();
}
catch (Exception ex) when (ex is not OperationCanceledException)
{
throw new InvalidOperationException(
$"The Azure deployment state for AKS environment '{Name}' contains an invalid scope.",
ex);
}
(subscriptionId, resourceGroupName) = await ResolveDeploymentScopeAsync(
scopedSubscription,
scopedResourceGroup,
context.Services,
context.CancellationToken).ConfigureAwait(false);
}
else
{View on GitHub (pinned to 25830f84bd)