microsoft/aspire · error · InvalidOperationException

The Azure resource scope value cannot be null.

Error message

The Azure resource scope value cannot be null.

What it means

ResolveScopeValueAsync resolves a deployment scope value that can be a literal string or an IValueProvider. If the IValueProvider returns null after awaiting GetValueAsync, the provisioner throws InvalidOperationException because an ARM deployment cannot proceed with a null scope (subscription/resource-group target).

Solutions

  1. Ensure the parameter/env var backing the scope value is set before running the AppHost.
  2. Verify the referenced resource producing the value ran and emitted its output (ordering/waiting).
  3. Fix custom IValueProvider implementations to return a non-null scope string.
  4. Validate the scope configuration (subscription id / resource group name) at startup.

Example fix

// before
var scope = builder.AddParameter("resourceGroupName"); // never supplied -> null value

// after
dotnet user-secrets set Parameters:resourceGroupName "my-rg"
// or provide a default:
var scope = builder.AddParameter("resourceGroupName", value: "my-rg");
Defensive patterns

Strategy: validation

Validate before calling

if (scopeParam is IValueProvider vp)
{
    var v = await vp.GetValueAsync(ct);
    if (string.IsNullOrWhiteSpace(v as string)) throw new InvalidOperationException("Scope value resolved to null; supply the parameter before provisioning.");
}

Type guard

static bool ResolvesToNonEmpty(IValueProvider provider) => provider.GetValueAsync(default).GetAwaiter().GetResult() is string s && s.Length > 0;

Try / catch

try
{
    await provisioner.GetOrCreateResourceAsync(resource, ct);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("scope value cannot be null"))
{
    logger.LogError(ex, "Deployment scope was null; check the parameter or referenced resource output supplying it.");
}

Prevention

When it happens

Trigger: A resource's scope (e.g. RunAsExisting/subscription/resource group scope via IValueProvider such as a parameter reference or output reference) resolves to null at provisioning time in ResolveScopeValueAsync.

Common situations: A configuration parameter or environment variable feeding the scope was not set, a referenced resource's output wasn't produced before resolution, or a custom IValueProvider implementation returned null.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting.Azure/Provisioning/Provisioners/BicepProvisioner.cs:1288

        AddDetail("correlation id", failureDetails.CorrelationId);

        return details.Count == 0 ? string.Empty : $" ({string.Join("; ", details)})";

        void AddDetail(string name, string? value)
        {
            if (!string.IsNullOrEmpty(value))
            {
                details.Add($"{name}: {value}");
            }
        }
    }

    private static async Task<string> ResolveScopeValueAsync(object scopeValue, CancellationToken cancellationToken)
    {
        return scopeValue switch
        {
            string value => value,
            IValueProvider valueProvider => await valueProvider.GetValueAsync(cancellationToken).ConfigureAwait(false) ?? throw new InvalidOperationException("The Azure resource scope value cannot be null."),
            _ => throw new NotSupportedException($"The scope value type {scopeValue.GetType()} is not supported.")
        };
    }

    private async Task<bool> TryCancelDeploymentAsync(IArmDeploymentCollection deployments, string deploymentName, ILogger resourceLogger, bool treatMissingOrInactiveAsCanceled)
    {
        try
        {
            await deployments.CancelAsync(deploymentName, CancellationToken.None).ConfigureAwait(false);
            resourceLogger.LogInformation("Cancellation requested for Azure deployment {DeploymentName}.", deploymentName);
            return true;
        }
        catch (RequestFailedException ex) when (treatMissingOrInactiveAsCanceled && (ex.Status == 404 || ex.Status == 409))
        {
            logger.LogInformation(ex, "Azure deployment {DeploymentName} was already absent or no longer active during cancellation.", deploymentName);
            resourceLogger.LogInformation("Azure deployment {DeploymentName} was already absent or no longer active during cancellation.", deploymentName);
            return true;
        }

View on GitHub (pinned to 25830f84bd)