function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Jason Kuzmak 12Jason Kuzmak 12 

Trying to return a list of custom object records to my collection variable via apex action

Hello all,

I'm building my first flow, which is now in flow builder. My first major hurdle is that I can't seem to send a string to an apex action, query some records using that string as a soql criterion, then return the list. 

My Apex action looks like this:
 

global class Flow_ChecklistTemplateItemGetter{
	@invocableMethod(label = 'Get Template Items' description = 'gets all Checklist Template Items whose "Applies_To" field contains the provided machine model')
	global static List<Checklist_Template_Item__c> getRelevantTemplateItems(List<String> modelList){
		
		String searchModel;
		
		// this will only be a single value
		for(String s : modelList){
			searchModel = s;
		}
		
		System.debug('SearchModel = '+searchModel);

		String queryString = 'Select Id, Checkbox_Options__c, Checklist_Template_Section__c, Objective__c, Required__c, Sort_Order__c From Checklist_Template_Item__c Where Applies_To__c Includes(:searchModel)';
		List<Checklist_Template_Item__c> itemList = Database.query(queryString);
		
	 	for(Checklist_Template_Item__c cti : itemList){
	 		System.debug('checklist template item = '+cti);
	 	}
	 	
	 	return itemList;
	}
}
"modelList" is only ever going to be a single value, which is why I assign it to its own string for querying. 

I get the error "The number of results does not match the number of interviews that were executed in a single bulk execution request". 
Well...no kidding. I don't want to only return one record just because I only had one string input. 

What I thought might be the reason was that my output variable was not a collection variable, but the collection variable I created in followup to that is un-selectable from my Apex action. 

I can only select variables that accept a single record. 
User-added image

Best Answer chosen by Jason Kuzmak 12
Jason Kuzmak 12Jason Kuzmak 12
It turns out, this error may have been caused by the need to return a list of lists to export to a collection variable. I had thought that collection variables were lists of sObjects, but they're actually a list containing a single other list. I modified my code by inputting the list of lists of junction objects that connect my Checklist Template to my Checklist Template Items, then outputting a list of lists of template items that I had queried in my apex code.
global class Flow_ChecklistTemplateItemGetter{
	@invocableMethod(label = 'Get Template Items' description = 'gets all Checklist Template Items whose "Applies_To" field contains the provided machine model')
	global static List<List<Checklist_Template_Item__c>> getRelevantTemplateItems(List<List<Checklist_Template_Item_Junction__c>> junctionListList){
		
		System.debug('junctionListList.size() = '+junctionListList.size());
		Set<String> itemIds = new Set<String>();
		// this will only be a single value
		for(List<Checklist_Template_Item_Junction__c> junctionList : junctionListList){
			System.debug('junctionList = '+junctionList);
			for(Checklist_Template_Item_Junction__c ctij : junctionList){
				System.debug('ctij = '+ctij);
				itemIds.add(ctij.Checklist_Template_Item__c);
			}
		}
		
		List<Checklist_Template_Item__c> itemQuery = [Select Id, Checkbox_Options__c, Checklist_Template_Section__c, Objective__c, Required__c, Sort_Order__c From Checklist_Template_Item__c Where Id In : itemIds];
		System.debug('itemQuery.size() = '+itemQuery.size());
		
		List<List<Checklist_Template_Item__c>> itemListList = new List<List<Checklist_Template_Item__c>>();
		List<Checklist_Template_Item__c> itemList = new List<Checklist_Template_Item__c>();
		for(Checklist_Template_Item__c cti : itemQuery){
			System.debug('cti = '+cti);
			itemList.add(cti);
		}
		itemListList.add(itemList);
		System.debug('itemListList.size() = '+itemListList.size());
		
	 	return itemListList;
	}
}

Even more confusing, as above, only one SObject list is required in your list of lists, since the collection variable you pass to the invocable in the first place is a list containing a single list of records. When I tried to build multiple lists with individual records to store in the master list, I got "The number of results does not match the number of interviews that were executed in a single bulk execution request."

All Answers

Jason Kuzmak 12Jason Kuzmak 12
It turns out, this error may have been caused by the need to return a list of lists to export to a collection variable. I had thought that collection variables were lists of sObjects, but they're actually a list containing a single other list. I modified my code by inputting the list of lists of junction objects that connect my Checklist Template to my Checklist Template Items, then outputting a list of lists of template items that I had queried in my apex code.
global class Flow_ChecklistTemplateItemGetter{
	@invocableMethod(label = 'Get Template Items' description = 'gets all Checklist Template Items whose "Applies_To" field contains the provided machine model')
	global static List<List<Checklist_Template_Item__c>> getRelevantTemplateItems(List<List<Checklist_Template_Item_Junction__c>> junctionListList){
		
		System.debug('junctionListList.size() = '+junctionListList.size());
		Set<String> itemIds = new Set<String>();
		// this will only be a single value
		for(List<Checklist_Template_Item_Junction__c> junctionList : junctionListList){
			System.debug('junctionList = '+junctionList);
			for(Checklist_Template_Item_Junction__c ctij : junctionList){
				System.debug('ctij = '+ctij);
				itemIds.add(ctij.Checklist_Template_Item__c);
			}
		}
		
		List<Checklist_Template_Item__c> itemQuery = [Select Id, Checkbox_Options__c, Checklist_Template_Section__c, Objective__c, Required__c, Sort_Order__c From Checklist_Template_Item__c Where Id In : itemIds];
		System.debug('itemQuery.size() = '+itemQuery.size());
		
		List<List<Checklist_Template_Item__c>> itemListList = new List<List<Checklist_Template_Item__c>>();
		List<Checklist_Template_Item__c> itemList = new List<Checklist_Template_Item__c>();
		for(Checklist_Template_Item__c cti : itemQuery){
			System.debug('cti = '+cti);
			itemList.add(cti);
		}
		itemListList.add(itemList);
		System.debug('itemListList.size() = '+itemListList.size());
		
	 	return itemListList;
	}
}

Even more confusing, as above, only one SObject list is required in your list of lists, since the collection variable you pass to the invocable in the first place is a list containing a single list of records. When I tried to build multiple lists with individual records to store in the master list, I got "The number of results does not match the number of interviews that were executed in a single bulk execution request."
This was selected as the best answer
mukkesh reddy 4mukkesh reddy 4


Jason Kuzmak 12

you are awesome man!! It worked smooooooooooooooooooooooooooooooooth !!

Marcio_FritschMarcio_Fritsch
For me it does not work whatever I do. If I just call an apex without any query it throws the error. Just calling out this apex under a console which returns a list with 2 or more records the error persists:

Console:
list<sobject> toUpdate = [select id from sobject limit 2]
upsert toUpdate;



there is a Flow which has the current apex invocable method:


 @InvocableMethod(label='Get Assignment Users' description = 'Get Assignment Users' category='Any')
    public static list<list<Result_UsersAssignment>> getUsersAssignment(list<list<Request_UsersAssignment>> lRequests) {
        list<list<Result_UsersAssignment>> oreturn = new list<list<Result_UsersAssignment>>();
        Result_UsersAssignment oUserAssign = new Result_UsersAssignment();
        map<string, string> mRelatedUsersIDs = new map<string, string>();
        map<id, user> mUsers = new  map<id, user>();
        oreturn.add(new list<Result_UsersAssignment>{oUserAssign});
        return oreturn;
    }


Error:
Error element GetAssignmentUsers (FlowActionCall).
The number of results does not match the number of interviews that were executed in a single bulk execution request.
Meghna Singh 5Meghna Singh 5
Hi Jason
Were you finally able to send list of list generic sobject of size more than 1 to the flow?
Would really appreciate your help here. Kindly reply
Thanks,
Meghna
Test User 101 9Test User 101 9

@Jason Kuzmak 12 and @mukkesh reddy 4

I am facing same issue I have to pass multiple type of objects list by using wrapper class. How i can pass nested list of wrapper class to apex action and return nested list to flows.
Input and output from flow collection type not supporting can you help me out? 

 

code snippet:

 public class Requests
    {    
        @InvocableVariable(label='Locations of DTC' description='Locations of DTC' required=true)
        public List<Schema.Location> locationList;
        @InvocableVariable(label='Order Product Summary' description='Order Product Summary')
        public List<OrderItemSummary> orderProductSummary;
        @InvocableVariable(label='Fulfillment Line Items' description='Fulfillment Line Items')
        public List<FulfillmentOrderLineItem> fullLineItems;
    }
    
    public class Results
    {    
        @InvocableVariable(label='External Reference of Locations for DTC' description='Set of Locations for DTC orders')
        public List<string> fulfillmentLocations;
        @InvocableVariable(label='Set of Locations for DTC' description='Set of Locations for DTC orders')
        public List<string> fulfillmentLocationIds;
    }

 @InvocableMethod(label='Get Fulfillment Location' description='Get Fulfillment Location With Threshold')
    public static List<List<Results>> getAvailableFulfillmentLocations(List<Requests> Requests)
    {
}

Jason Kuzmak 12Jason Kuzmak 12

@Test User 101 9

I think it might be best to post this as a question to the whole developer forum, for exposure. I was lucky because I didn't have to work with wrapper classes in my example, and I'm wondering if / how flows would interpret something like that. I think it's too different from my use case for me to be able to help you out. 

David Roberts 4David Roberts 4
The answer appears to be as described by Keiji in https://trailblazers.salesforce.com/answers?id=9064S000000DfawQAC
if(!inputparms.isEmpty()){
         //do stuff
         return lstLstReturns;
} else return null;
//endif inputparms has values

I'm trying it now...