0

I am trying to run a record triggered flow when multiple records are created. What I have now, works perfectly until I try to enter more than one Record at a time. I get the following error:

The number of results does not match the number of interviews that were executed in a single bulk execution request.

Here is my code:

@InvocableMethod
public static List<List<String>> generateIndustryLinkNumber() {
        final String strChars = '0123456789ABCDEF';
        String strRandom = '';
        List<List<String>> lstLstAllRandoms = new List<List<String>>();
        List<String> lstRandoms = new List<String>();
        Boolean runAgain = true;
      
        while (runAgain) {
            while (strRandom.length() < 10) {
                Integer idx = Math.mod(Math.abs(Crypto.getRandomInteger()), strChars.length());
                strRandom += strChars.substring(idx, idx+1);
            }
            
            lstRandoms.add(strRandom);
            
            List<Contact> lstExistingContacts = [SELECT Id FROM Contact WHERE Industry_Link__c IN :lstRandoms LIMIT 1];
            
            if (lstExistingContacts.isEmpty()) {
                runAgain = false;
            } 
        }
        System.debug(JSON.serializePretty(lstRandoms));
        lstLstAllRandoms.add(lstRandoms);
        return lstLstAllRandoms;    
  
    }

Generate a random number, check that its unique, if not unique generate another random number and check that its unique, and return. This code is called in a flow that looks like this: enter image description here

Multiple contacts can be loaded at once, and I want the flow and class to fire on every single one. So, I used a loop & collection variable. Again, this works when just one record is created, but errors out when there's multiple.

What am I doing wrong? I already switched from returning a List<String> to List<List<String>> as I've seen online but yet I still hit the same error. Any advice? Thanks!

5
  • Make sure to pass the method n inputs and return n outputs. However, there are structural problems with this code including a query in a loop that will become more and more troublesome as you consume a higher and higher proportion of the available random number set.
    – Phil W
    Jul 28, 2022 at 21:01
  • I would recommend using a combination of Datetime.now().time() and the last part of the record's ID to generate a unique value. Not random but guaranteed unique also not easily guessable. Obviously requires the ID to already be set...
    – Phil W
    Jul 28, 2022 at 21:10
  • what do you mean pass n inputs and return n outputs? @PhilW
    – user92335
    Jul 28, 2022 at 21:18
  • If you want n results (e.g. 6 lists of numbers) then pass in n values (e.g. 6 IDs).
    – Phil W
    Jul 28, 2022 at 21:40
  • how do i do that? i won't know how many results i want because it would depend on however many records are being created at the time @PhilW
    – user92335
    Jul 28, 2022 at 21:45

2 Answers 2

0

You need an input parameter to tell you how many elements are involved.

public class Request {
  // This can actually be whatever you want, we don't use it
  // except to figure out how many records we're expecting to
  // generate strings for.
  @InvocableVariable public Id recordId;
}
@InvocableMethod
public static String[] generateIndustryLinkNumber(Request[] requests) {
  String[] results = new String[0];
  //... logic here ...//
  return results;
}

Note that you're violating the "soql in a loop" scenario in a bad way. You should bulkify your code, like this:

Set<String> tempValues = new Set<String>();
while(results.size() != requests.size()) {
  while(tempValues.size() < requests.size()) {
    tempValues.add(createRandomString());
  }
  for(Contact record: [SELECT Industry_Link__c FROM Contact WHERE Industry_Link__c = :tempValues]) {
    tempValues.remove(record.Industry_Link__c);
  }
}
results.addAll(tempValues);

Obviously, you still have a query in a loop, but you're much less likely to hit governor limits, as you only need to retry an entire batch (which may be hundreds of records) instead of one record at a time.

This is because flows are bulkified, meaning that one interview is created for each record in bulk, rather than all records being in a single interview. You need to return one output value for each input value. This also means you probably don't need the loop in your flow, as there is a 1:1 ratio of records to interviews.

1
  • added that input parameter however whenever i do return results its empty?
    – user92335
    Jul 28, 2022 at 22:32
0

When apex trigger/record-trigger flow runs -> it calls the Invocable method

Case 1: if one record, it is still fine.

Case 2: if N records, it will put N params to Invocable method, we need to return a list with N elements. Otherwise, it will return error "The number of results does not match the number of interviews".

You must log in to answer this question.