Repository navigation
Unable to re-use AppRoleAssignment instance #3197
Description
Describe the bug
I'm creating App Registrations, Service Principals, then assign an App role to that service principal.
The App role assignment is done like this:
var assignment = new AppRoleAssignment { PrincipalId = Guid.Parse(servicePrincipalObjectId), ResourceId = Guid.Parse(api.Id!), AppRoleId = role.Id };
await graph.ServicePrincipals[servicePrincipalId].AppRoleAssignments.PostAsync(assignment);`
Depending on timing it could be that this operation returns an ODataError with code 'Request_ResourceNotFound' (I really wished Microsoft would learn the concept of hot writes... feels kinda amateur hour to have retries everywhere, but I digress). So, I created a retry mechanism when getting that exception that just calls AppRoleAssignments.PostAsync again after some time with circuit breaker and all. However, from the second invocation of AppRoleAssignments.PostAsync fails with an 'AdditionalData can not be null' error.
So it seems the aborted operation changes the AppRoleAssignment in a way that it can't be re-used and has to be constructed again.
Expected behavior
I would expect to be able to re-use my AppRoleAssignment object
How to reproduce
You need to create an App Registration with a custom role to run this sample. Run under an account that has AppRoleAssignment.ReadWrite.All and Application.ReadWrite.OwnedBy permissions.
All error handling and retry behavior has been stripped away for brevity
var app = await graph.Applications.PostAsync(
new Application { DisplayName = displayName, SignInAudience = "AzureADMyOrg" });
var sp = await graph.ServicePrincipals.PostAsync(
new ServicePrincipal { AppId = app.Id });
var apiAppId = "ClientId of App Registration that has the 'name of-custom-role' role";
var apis = await graph.ServicePrincipals.GetAsync(r =>
{
r.QueryParameters.Filter = $"appId eq '{apiAppId}'";
}).ConfigureAwait(false);
var roleValue = "name-of-custom-role-on";
var api = apis?.Value?.FirstOrDefault();
var role = api.AppRoles?.FirstOrDefault(x => x.Value == roleValue);
var assignment = new AppRoleAssignment
{
PrincipalId = Guid.Parse(sp.Id),
ResourceId = Guid.Parse(api.Id!),
AppRoleId = role.Id
};
await graph.ServicePrincipals[servicePrincipalId].AppRoleAssignments.PostAsync(assignment);
SDK Version
5.51.0
Latest version known to work for scenario above?
No response
Known Workarounds
re-instantiate AppRoleAssignment before trying the create the app role assignment again.
Debug output
Click to expand log
```</details>
### Configuration
- OS: Win 11 2025H2
- Architecture: x64
- Issue is present when deployed on Azure App service as well so it's not environment specific
- the SDK is included with the package Microsoft.Identity.Web.GraphServiceClient 4.16.1.
### Other information
_No response_
Activity
Saad-elnagar commentedon Oct 21, 2026
Hi! I’d like to investigate this issue and contribute a fix.
The behavior described here is worth addressing: when a
PostAsyncrequest fails, retrying with the sameAppRoleAssignmentinstance results in anAdditionalData can not be nullerror, forcing callers to recreate the model just to retry the operation.I’d like to trace how the request serialization pipeline handles the model instance, identify what changes during the first request, and determine whether the SDK can safely support reusing the same request model across retries.
My proposed approach is to:
Would it be okay for me to investigate this and submit a PR with the fix and regression tests?