skip to Main Content

While working with the Microsoft Graph API, I’m trying to list the tasks of a specified (i.e., not me) user.

If I use the Graph Explorer with the following URL (which I found by navigating through the Resources on the left-hand side of the Graph Explorer) …

https://graph.microsoft.com/v1.0/users/{user-id}/planner/plans/{plannerPlan-id}/buckets/{plannerBucket-id}/tasks

… I receive the following response …

{
    "error": {
        "code": "",
        "message": "No HTTP resource was found that matches the request URI 'https://tasks.office.com:444/taskapi/V3.0/users('REMOVED: A USER ID')/details/plans('REMOVED: A PLAN ID')/buckets('REMOVED: A BUCKET ID')/tasks'.",
        "innerError": {
            "message": "No routing convention was found to select an action for the OData path with template '~/entityset/key/navigation/navigation/key/navigation/key/navigation'.",
            "date": "2024-04-09T08:12:20",
            "request-id": "67b71584-da23-4e51-823c-ff3ed3521f34",
            "client-request-id": "8fda60ca-7ee2-82bc-5035-52c3bb31503c"
        }
    }
}

The user, plan and bucket ID that I’m specifying have all been obtained from other Graph API requests.

I also get the same response by using (C#) …

response = await graphClient.Users[userId].Planner.Plans[planId].Buckets[bucketId].Tasks.GetAsync();

… from the Microsoft.Graph library.

Also, if I go ‘back up’ the URL and use only …

https://graph.microsoft.com/v1.0/users/{user-id}/planner

… then I receive …

{
    "error": {
        "code": "",
        "message": "You do not have the required permissions to access this item.",
        "innerError": {
            "date": "2024-04-09T08:18:54",
            "request-id": "54f31cca-cf01-4390-bae7-5a1f00afc1ed",
            "client-request-id": "63094425-9963-d539-55af-2e9e15d62d7e"
        }
    }
}

I then clicked on Modify permissions, and it lists the following as being necessary:

  • Tasks.Read
  • Group.Read.All
  • Tasks.ReadWrite

All of these have been granted.

enter image description here

So why can’t it find the tasks in the specified plan/bucket, and why does it appear to be missing permissions?

UPDATE:
The Tasks.Read.All permission has been granted (since before the original post) as type Application.

Also, I can obtain another user’s tasks by calling …

graphClient.Users[userId].Planner.Tasks.GetAsync()

… but that retrieves every task across all buckets and all plans. The following two methods exist in the Microsoft.Graph library and are listed in Graph Explorer …

graphClient.Users[userId].Planner.Plans[planId].Buckets[bucketId].Tasks.GetAsync()
graphClient.Users[userId].Planner.Plans[planId].Tasks.GetAsync()

… both those methods would help to narrow the scope of the returned tasks, but calling either of those methods results in an exception …

Microsoft.Graph.Models.ODataErrors.ODataError: No HTTP resource was found that matches the request URI ‘https://tasks.office.com:444/taskapi/V3.0/users(‘MY USER ID’)/details/plans(‘MY PLAN ID’)/tasks’.

I am 100% certain that the planId and bucketId arguments are correct – I’m taking them from the result of other calls and am using them in other successful calls.

Is this a bug, is another permission needed, or have I misunderstood something?

2

Answers


  1. The same issue for me, even the request GET /v1.0/me/planner/plans/{plan_id} fails with the error

    No routing convention was found to select an action for the OData path with template ‘~/entityset/key/navigation/navigation/key’.

    I’m not able to read tasks of other users with delegated permission. Based on this, Tasks.Read and Tasks.ReadWrite allow to read tasks of signed-in user, not of other users.

    You will need to use application permissions Tasks.Read.All, call the endpoint GET /v1.0/users/{user_id}/planner/tasks and filter tasks by planId and bucketId. From my testing, the server side filtering neither by planId nor bucketId is supported. It must be done on the client

    var result = await graphClient.Users[userId].Planner.Tasks.GetAsync();
    
    Login or Signup to reply.
  2. I agree with @user2250152 and @TinyWang, you cannot read tasks of other users using Delegated permissions. As Graph Explorer works with Delegated permissions, you can only get tasks of signed-in user.

    When I tried to get the tasks of other users via Graph Explorer, I too got same error like this:

    GET https://graph.microsoft.com/v1.0/users/userID/planner/tasks
    

    Response:

    enter image description here

    To get the tasks of other users, you need to switch to client credentials flow by granting permissions of Application type that generates app-only token.

    In my case, I registered one application and granted Tasks.Read.All permission of Application type by granting admin consent:

    enter image description here

    When I ran below sample C# code that uses client credentials flow, I got the response successfully with other user tasks details like this:

    using Azure.Identity;
    using Microsoft.Graph;
    using System;
    
    class Program
    {
        static async Task Main(string[] args)
        {
            var scopes = new[] { "https://graph.microsoft.com/.default" };
            var tenantId = "tenantId";
            var clientId = "appId";
            var clientSecret = "secret";
    
            var options = new TokenCredentialOptions
            {
                AuthorityHost = AzureAuthorityHosts.AzurePublicCloud,
            };
    
            var clientSecretCredential = new ClientSecretCredential(tenantId, clientId, clientSecret, options);
    
            var graphClient = new GraphServiceClient(clientSecretCredential, scopes);
    
            try
            {
                var tasks = await graphClient.Users["userId"].Planner.Tasks.GetAsync();
    
                Console.WriteLine("Tasks:");
                foreach (var task in tasks.Value)
                {
                    Console.WriteLine("---------------------------------------------------");
                    Console.WriteLine($"Task Title: {task.Title}");
                    Console.WriteLine($"Task ID: {task.Id}");
                    Console.WriteLine($"Task Bucket ID: {task.BucketId}");
                    Console.WriteLine($"Task Plan ID: {task.PlanId}");
                }
                Console.WriteLine("---------------------------------------------------");
            }
            catch (Exception exception)
            {
                Console.WriteLine($"{exception.GetType().FullName}: {exception.Message}");
            }
        }
    }
    

    Response:

    enter image description here

    Reference:
    List tasks – Microsoft Graph

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search