I'm trying to pass a collection variable of opportunities from a flow to apex. Here is my apex and a picture of my action element. Why can't I pass my collection of opportunities (socOpportunity in my flow) to apex via the Action element? FYI, the apex code is used in case hundreds of opportunity records are imported at once. The code is very basic; it's matching products to opportunity records based on the vehicle preference on the opportunity record.

public class OpportunityProductMatching {

@InvocableMethod(label='Match Opportunities to Products' category='Opportunity')
public static List<List<Opportunity>> matchOpportunities (List<Opportunity> listOpp){
    List<List<Opportunity>> listFlowOpps = new List<List<Opportunity>>();
    List<OpportunityLineItem> listOppLineItem = new List<OpportunityLineItem>();
    List<Product2> listProduct = new List<Product2>(
        [SELECT Id, Name, Manufacture__c, Model__c, Year__c, Price__c, Miles__c
         FROM Product2
         WHERE IsActive = true]
    for(Opportunity opp : listOpp) {
        for(Product2 prod : listProduct) {
            if (opp.Vehicle_Preference__c == prod.Model__c) {
                OpportunityLineItem oppLineItem = new OpportunityLineItem();
                oppLineItem.OpportunityId = opp.Id;
                oppLineItem.Product2Id = prod.Id;
    insert listOppLineItem;
    return listFlowOpps;


Flow: enter image description here

Thanks for your help in advance!

1 Answer 1


Flows are bulkified, which is why the apex method accepts a list of records. You would only pass in 1 record in the flow, but the apex method accepts a list.

To get around this, your apex method can accept a List<List<sObject>> so that you can pass a record collection variable from your flow into the apex method.

  • Yes, I realize this. Are you saying my matchOpportunities method should receive a List<List<Opportunity>> rather than List<Opportunity>?
    – user82573
    Commented Apr 19, 2021 at 14:07
  • That is correct.
    – mike537
    Commented Apr 20, 2021 at 2:52
  • Also, as an FYI, you don't need the new List<Product2>() code surrounding your query since queries return a list by default. You're creating extra work by creating a list from a list.
    – mike537
    Commented Apr 20, 2021 at 2:55
  • The record collection variable that you pass into your apex method will be at listOpp[0] if listOpp is a List<List<Opportunity>>
    – mike537
    Commented Apr 20, 2021 at 3:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .