microsoftgraph / microsoftgraph/msgraph-sdk-dotnet

Teams AddAsync/PostAsync is totally and utterly broken

Open
#1,366 8 comments 3 reactions 1 assignee View on GitHub

@rkodev is already working on this.

Since Apr 17, 2025.

Request: enhancement
Dominant language
C#
Stars
789
Forks
264
Avg merge
15h 17m
Merged PRs (30d)
3

Description

Describe the bug
A reasonable person might think that this was the correct usage of the API:
var newteam = await GraphClient.Teams.Request().AddAsync(team, cancellationToken: CancellationToken);
but noooo, that just returns null.

Another reasonable person might see that there is a AddResponseAsync and try:

var channelResponse = await GraphClient.Teams.Request().AddResponseAsync(team, cancellationToken: CancellationToken);
var newteam = await channelResponse.GetResponseObjectAsync();

bot noooooo, that also just returns null. (FYI, there is no overload of GetResponseObjectAsync that takes CancellationToken, which is a bug in itself)

A totally fucking idiot might design the API to actually be called in this way:

         var v = await PostInTaskChannel(MessageFactory.Text(JsonConvert.SerializeObject(team)));
         var channelResponse = await GraphClient.Teams.Request().AddResponseAsync(team, cancellationToken: CancellationToken);
         if (!channelResponse.HttpHeaders.TryGetValues("Location", out var headerValues) ||
             headerValues.First().Split('\'', StringSplitOptions.RemoveEmptyEntries) is not { Length: > 3 } operationRequest)
            throw new("Unknown error, the request did not return the proper response:" + JsonConvert.SerializeObject(channelResponse.HttpHeaders));
         TeamsAsyncOperation? operation = null;
         var firstRequest = true;
         do
         {
            try
            {
               operation = await GraphClient.Teams[operationRequest[1]].Operations[operationRequest[3]].Request().GetAsync(CancellationToken);
               firstRequest = false;
            }
            catch
            {
               if (firstRequest) //sometimes it cannot find the operation, presumable because of hitting another server
                  operation = new() { Status = TeamsAsyncOperationStatus.InProgress };
               else throw;
            }
            if (operation.Status == TeamsAsyncOperationStatus.InProgress)
               await Task.Delay(TimeSpan.FromMilliseconds(100));
         } while (operation.Status is TeamsAsyncOperationStatus.InProgress);

         if (operation.Status is not (TeamsAsyncOperationStatus.Succeeded or TeamsAsyncOperationStatus.NotStarted))
            throw new(JsonConvert.SerializeObject(operation.Error));

         var newTeam = await GraphClient.Teams[operationRequest[1]].Request().GetAsync(CancellationToken);

And why is the last outcome of an successful operation TeamsAsyncOperationStatus.NotStarted?!?!?!?!?

Expected behavior
var newteam = await GraphClient.Teams.Request().AddAsync(team, cancellationToken: CancellationToken);
works... or atleast returns an "TeamsCreationAsyncResult" that can be used to query the further result.

Client version
4.29

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.