4

I'm getting the error "The number of results does not match the number of interviews that were executed in a single bulk execution request" when I insert more than one record into an object that has a record-triggered Flow attached that calls an invocable method to do some data lookup. I'd love some help resolving this; here's the situation:

The real business logic is somewhat complex, but I've created a very simple demonstration scenario so it's easy to reproduce. The goal is to provide a lookup function that returns a list of Strings to a Flow text collection variable when a text value is passed in as an argument. Subsequent elements in the flow determine whether additional records should be created by testing if the collection contains a value in the incoming record. My test scenario simply outputs the return values. OK the setup:

Custom object, "Invoke__c"; two custom fields (text), "Input__c" and "Output__c".

Invocable method:

global with sharing class TestInvocable {
    @InvocableMethod(
            Label='Test invocable'
            Description='Return a list of user last names by passing in a first name.'
            Category='Testing'
    )
    global static List<List<String>> testInvocable(List<String> firstNames) {
        for (String firstName : firstNames) {
            firstName = String.escapeSingleQuotes(firstName);
        }
        List<User> users = [
                SELECT Id, LastName
                FROM User
                WHERE FirstName IN :firstNames
        ];
        List<String> lastNames = new List<String>();
        for (User user : users) {
            lastNames.add(user.LastName);
        }
        return  new List<List<String>>{lastNames};
    }
}

Flow: testInvocableTrigger

enter image description hereThe five elements:

Start: record-triggered, after-save on the Invoke__c object

Action: our Test invocable method; pass in $Record.Input__c to the firstNames argument

Loop: over the variable associated automatically with the action above

Assignment: for each item in the loop, "Add" the current items value to a "stringOfNames" single value text var

Update Records: after last loop item, update the Invoke__c record passed in by spec'ing condition of Id = $Record.Id; update the Output__c field to the stringOfNames var.

Testing this out: If you insert a single record into the Invoke__c object (specifying a user first name for the Input__c field), it will succeed, and the Output__c field of the incoming record will be updated by the Flow with a concatenation of all the last names for users that match the user first name passed in. If you insert 2 or more records, the operation will fail with error "The number of results does not match the number of interviews that were executed in a single bulk execution request".

Comments: I've seen a few posts that mention needing to have "input size and output size match", but no one actually explains what this means, or shows how this is demonstrated in code or in Flow design. It seems unconscionable that we would be restricted to outputting the same number of items from an invocable as the number of records in the batch that get "bulkified" by the Flow engine. That would make any kind of utility function like I propose impossible to implement.

Anyone have suggestions, a fix, or more information about this issue? Thanks very much in-advance. -Ben

3 Answers 3

2

In this case, the testInvokable method is combining the results of the soql query into a single list of names. This means it only ever returns one result regardless of how many firstNames are provided.
To get the output you're looking for, you'll want to create a list of last names returned by the query specific to each first name. This ensures that the number of outputs aligns with the number of inputs.

Here's an example

global with sharing class TestInvocable {
@InvocableMethod(
        Label='Test invocable'
        Description='Return a list of user last names by passing in a first name.'
        Category='Testing'
)
global static List<List<String>> testInvocable(List<String> firstNames) {
    Map<String, List<String>> mapLastNamesByFirstName = new Map<String,List<String>>();
    for (String firstName : firstNames) {
        mapLastNamesByFirstName.put(String.escapeSingleQuotes(firstName), new List<String>());
    }
    List<User> users = [
            SELECT Id, FirstName, LastName
            FROM User
            WHERE FirstName IN :firstNames
    ];
    for (User user : users) {
        mapLastNamesByFirstName.get(user.FirstName).add(user.LastName);
    }
    
    List<List<String>> results = new List<List<String>>();
    
    for(String firstName : firstNames) {
        results.add(mapLastNamesByFirstName.get(String.escapeSingleQuotes(firstName)));
    } 

    return results;
}

}

2
  • Hi Scott - thanks much for your reply, and complete code sample! Unfortunately, I get the same error with this method. I do appreciate your approach - it makes sense, and I had actually implemented something like this in my "real world" code first time around. The fact it didn't work there was what lead me to post here. Were you able to get this to work in a bulk context? Works fine for single record. Thanks again.
    – Ben
    Oct 5, 2020 at 18:11
  • OK, super-embarrassed to admit this, but...your solution works fine. In my test scenario, I'd failed to activate the flow that tapped into the latest code. So - many thanks, Scott!
    – Ben
    Oct 5, 2020 at 19:14
0

I'm sure this is bad code, but it working for me:

//this is dumb and I don't understand why I have to do it
//This method will make sure we have as many results as requests
@TestVisible
static List<List<Results>> matchRequestSize(Integer reqSize, List<Results> resultList){
    System.debug('matchRequestSize is running.....');
    System.debug('reqSize:' +reqSize);
    System.debug('resultList Size: ' + resultList.size());
    List<List<Results>> resultWrapper = new List<List<Results>>();
    resultWrapper.add(resultList);
    while(resultWrapper.size() < reqSize){
        resultWrapper.add(new List<Results>());
    }
    System.debug('resultWrapper size: ' + resultWrapper.size());
    return resultWrapper;
}
0

After running into same Issue und analyzing the Issue this is the answer:

  1. Issue is caused by Flows and Processes containing an "Invocable Method".
  2. Flows and Processes REQUIRE the same number of Results read from the Invocable Method as as Requests provided to the Invocable Method.
  3. The Return Type must NOT be the same as the Request type.
  4. The Return Type VOID is NOT VALID for Flows and Processes.
  5. Workaround for Users which return fewer Results than Requests: Input Parameter is List<List<...>> and Response is also List<List<...>>. Use the inner List and add all Requests and Reponses to the inner List. The outer List always contains the inner List. This results in the same number of Requests and Responses (1 List with 1 List)

Last Point Credits go to another User:https://developer.salesforce.com/forums/?id=9062I000000QwROQA0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.