microsoft/aspire · error · ArgumentException

'ownerResource' and 'identityResource' must both be null…

Error message

'ownerResource' and 'identityResource' must both be null (for global role assignments) or both be non-null (for targeted role assignments).

What it means

AzureRoleAssignmentResource enforces that role assignments are either global (attached to no owner resource) or targeted (attached to a specific owner resource). ValidateOwnerAndIdentity throws ArgumentException when exactly one of ownerResource/identityResource is null, because the constructor factory APIs require the pair to be consistent. The exception names whichever argument is null to point at the mismatched half.

Solutions

  1. Ensure both ownerResource and identityResource are provided together for targeted role assignments.
  2. If the role assignment should be global, pass null for both arguments.
  3. Check custom wrapper/extension methods that may pass the identity conditionally and make the null-ness symmetric.

Example fix

// before
var roles = new AzureRoleAssignmentResource("roles", scopeGroup, ownerResource, null);
// after
var roles = new AzureRoleAssignmentResource("roles", scopeGroup, ownerResource, identityResource);
Defensive patterns

Strategy: validation

Validate before calling

if ((ownerResource is null) != (identityResource is null))
{
    throw new ArgumentException("ownerResource and identityResource must both be null or both non-null.");
}

Type guard

bool isValidPair = (ownerResource is null && identityResource is null) || (ownerResource is not null && identityResource is not null);

Try / catch

try { /* construct role assignment */ } catch (ArgumentException ex) when (ex.Message.Contains("ownerResource")) { /* fix call site: pass both or neither */ }

Prevention

When it happens

Trigger: Calling the AzureRoleAssignmentResource constructor (or WithRoleAssignments-style APIs that feed it) with an ownerResource but a null identityResource, or vice versa.

Common situations: Hand-constructing role assignment resources in custom extension methods; refactoring code that passes an identity only conditionally; mixing the global API surface (no owner) with an identity parameter by mistake.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


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

Appendix: source

Thrown at src/Aspire.Hosting.Azure/AzureRoleAssignmentResource.cs:59

    /// <remarks>
    /// This is the resource on which <c>WithRoleAssignments</c> was called. Its managed identity
    /// is exposed via <see cref="IdentityResource"/>.
    /// When <c>WithRoleAssignments</c> is called using an <see cref="AzureUserAssignedIdentityResource"/>,
    /// OwnerResource and IdentityResource are the same.
    /// </remarks>
    public IResource? OwnerResource { get; } = ValidateOwnerAndIdentity(ownerResource, identityResource);

    /// <summary>
    /// Gets the user-assigned managed identity whose principal receives the role assignments,
    /// or <see langword="null"/> for global role assignments that are granted to the deployment principal.
    /// </summary>
    public AzureUserAssignedIdentityResource? IdentityResource { get; } = identityResource;

    private static IResource? ValidateOwnerAndIdentity(IResource? ownerResource, AzureUserAssignedIdentityResource? identityResource)
    {
        if ((ownerResource is null) != (identityResource is null))
        {
            throw new ArgumentException(
                $"'{nameof(ownerResource)}' and '{nameof(identityResource)}' must both be null (for global role assignments) or both be non-null (for targeted role assignments).",
                ownerResource is null ? nameof(ownerResource) : nameof(identityResource));
        }

        return ownerResource;
    }
}

View on GitHub (pinned to 25830f84bd)