Share via

[Microsoft Purview] DiscoveryClient Query Issue

Mofei Zhuang 140 Reputation points Microsoft Employee
2026-03-18T12:47:19.9733333+00:00

My scenario is I have a set of name, and I want to search all the target entity type which's name in this set.

So, I created the below logic to do that, but always return me the same error :

{"requestId":"60531c10-b37e-4e8d-b36d-7de7f87c88e6","errorCode":"RequestIllegalArgument","errorMessage":"Illegal argument detected in request payload: operator should not be null. Please check the payload and try again."}

Just want to know if there have a best practice code example for my search requirement ?

Here is my code :

 public async Task<IEnumerable<SearchResultValue>> SearchEntityByResourceNameAsync(IEnumerable<string> names, string typeName)
 {
     var filterObj = new
     {
         attributeName = "name",
         @operator = "in",
         attributeValue = names.ToList()
     };

     var finalPayload = new
     {
         typeName = typeName,
         filter = filterObj 
     };

     var resList = new List<SearchResultValue>();
     string? continuationToken = null;
     var config = new QueryConfig { Limit = 1000 };

     do
     {
         config.Filter = BinaryData.FromObjectAsJson(filterObj);
         config.ContinuationToken = continuationToken;

         var response = await purviewClient.DataMapClient.GetDiscoveryClient().QueryAsync(config);

         if (response?.Value?.Value != null)
         {
             resList.AddRange(response.Value.Value);
         }

         continuationToken = response.Value.ContinuationToken;

     } while (!string.IsNullOrEmpty(continuationToken));

     return resList;
 }
Microsoft Security | Microsoft Purview

2 answers

Sort by: Most helpful
  1. Manoj Kumar Boyini 16,810 Reputation points Microsoft External Staff Moderator
    2026-03-19T19:53:36.09+00:00

    Hi Mofei Zhuang,

    The error you’re encountering is not because the operator is missing in your code. It happens because the filter payload being sent to the Purview Discovery API does not match the structure that the service expects, so the backend fails to parse it and returns the misleading message “operator should not be null.”

    In Discovery queries, filters are expected to follow a logical structure. The pattern of using a single condition with an array of values (for example, using an in operator with a list) is not reliably supported. When this pattern is used, the service cannot correctly bind the filter, which leads to the error you are seeing.

    The reliable approach for your scenario is to structure the filter as a logical condition where each name is evaluated individually. This is typically done by combining multiple equality conditions under a logical operator, rather than trying to pass a list of values in a single condition. This aligns with how the Discovery API expects filters to be defined and ensures consistent behavior.

    Also note that if you intend to restrict the search to a specific entity type, that constraint needs to be explicitly included in the query; otherwise, the search will run across all entity types.

    the issue is caused by an unsupported filter pattern rather than a missing operator. Once the filter is restructured into a proper logical format, the query should work as expected.

    Hope this helps, Please let us know if you have any questions and concerns.

    Was this answer helpful?

    0 comments No comments

  2. AI answer

    2026-03-18T12:47:38.74+00:00

    The Discovery QueryAsync API does not support an operator = "in" with an array value the way the sample code is building it. The error operator should not be null is coming from an invalid filter shape in the request payload.

    Discovery filters must follow the documented pattern used in the SDK samples: a top-level object with logical operators (and, or, not) whose values are arrays of condition objects, and each condition object that uses attributeName must have a scalar attributeValue and a supported operator such as eq, ne, contains, prefix, gt, ge, lt, le, or timerange.

    To search by multiple names, build an or array of individual eq conditions instead of trying to use in. For example (C#-style, matching the SDK samples):

    public async Task<IEnumerable<SearchResultValue>> SearchEntityByResourceNameAsync(IEnumerable<string> names, string typeName)
    {
        var nameConditions = names
            .Select((n, i) => new Dictionary<string, object>
            {
                ["$id"] = $"name-{i}",
                ["attributeName"] = "name",
                ["operator"] = "eq",
                ["attributeValue"] = n
            })
            .Cast<object>()
            .ToArray();
    
        var filter = new Dictionary<string, object>
        {
            ["$id"] = "root",
            ["and"] = new object[]
            {
                new Dictionary<string, object>
                {
                    ["$id"] = "type",
                    ["entityType"] = typeName
                },
                new Dictionary<string, object>
                {
                    ["$id"] = "names",
                    ["or"] = nameConditions
                }
            }
        };
    
        var resList = new List<SearchResultValue>();
        string? continuationToken = null;
    
        do
        {
            var config = new QueryConfig
            {
                Limit = 1000,
                Filter = BinaryData.FromObjectAsJson(filter),
                ContinuationToken = continuationToken
            };
    
            var response = await purviewClient
                .DataMapClient
                .GetDiscoveryClient(apiVersion: "2023-09-01")
                .QueryAsync(config);
    
            if (response?.Value?.Value != null)
            {
                resList.AddRange(response.Value.Value);
            }
    
            continuationToken = response.Value.ContinuationToken;
    
        } while (!string.IsNullOrEmpty(continuationToken));
    
        return resList;
    }
    

    Key points based on the official samples:

    • Filter must be a JSON object with logical operators (and, or, not) and/or simple fields like entityType, objectType, classification, etc., as shown in the Query/QueryAsync examples.
    • Attribute-based filters use the pattern:
        {
          "attributeName": "name",
          "operator": "eq|ne|contains|prefix|gt|ge|lt|le|timerange",
          "attributeValue": "..." // scalar, not array
        }
      
    • To match multiple values, combine multiple attribute filters with "or": [ ... ] instead of using in.

    Following this pattern aligns the payload with the supported schema and avoids the operator should not be null error.


    References:

    AI-generated content may be incorrect. Read our transparency notes for more information.

    Was this answer helpful?

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.