0

I have an Apex class that matches Lead records to existing Contact records based on a phone number input. I'm using @InvocableMethod to include it in a Flow. The Flow works as designed when I insert a single Lead record, but returns the error The number of results does not match the number of interviews that were executed in a single bulk execution request when I attempt to process multiple Lead records (e.g. via Workbench).

I believe this is the same issue described here: Bulkification of Flow with invocable action - error re: number of results - how do I resolve?, but being new to Apex, I am struggling to understand how to get the input/output numbers to match for my use case.

An example of my Apex class is below:

public class matchLeadToContact{

@InvocableMethod(label='Match Lead to Contact' description='Matches incoming Leads to Contact records based on phone number' category='Lead')

public static List<String> getContactRecords(List<methodInputs> leadRecord) {

    String leadMobilePhone = leadRecord[0].MobilePhone;
    String leadHomePhone = leadRecord[0].Phone;

    leadHomePhone = leadHomePhone.replaceAll('^0-9', '');
    leadMobilePhone = leadMobilePhone.replaceAll('^0-9', '');

    List<String> contactRecord = new List<String>();
    
    List<Contact> contacts = [SELECT Id FROM Contact WHERE Phone =: leadMobilePhone OR Phone =: leadHomePhone LIMIT 1];
    
    for (Contact contact : contacts) {
        contactRecord.add(contact.Id);
    }
    
    return contactRecord;

}

//input details that come to apex from flow
public class methodInputs{
    @InvocableVariable(required=true)
    public String MobilePhone;
    @InvocableVariable(required=true)
    public String Phone;
}}

Might someone be able to explain why I am receiving the error even though my SOQL query is limited to a single result? How do I fix this?

2
  • You limit the number of Contacts to 1 in the query so the size of the "contactRecord" return list will always be 1, while the size of the input list of lead records will clearly vary. Make sure that you return the same sized list as you receive.
    – Phil W
    Mar 22 at 15:48
  • Thanks @PhilW. This is now making sense conceptually (which is progress for me). I have removed LIMIT 1 from the SOQL query and am trying to add a null value for the Contact output list in the event that no match is found. Can you point me in the right direction? for (Contact contact : contacts) { if (!contacts.isEmpty()) { contact = contacts[0]; } else { contact = 'No Result'; } contactRecord.add(contact); } return contactRecord;
    – JaredC
    Mar 22 at 16:39

1 Answer 1

1

You need to return a result for each input, making the input and output arrays the same size (and the same order).

Try something like:

public static List<String> getContactRecords(List<MethodInputs> leads) {
    Set<String> phones = new Set<String>();

    // Collect all the mobile and phone numbers, ignoring empty values
    for (MethodInputs lead : leads) {
        String phone = lead.MobilePhone?.replaceAll('^0-9', '');

        if (String.isNotBlank(phone)) {
            phones.add(phone);
        }

        phone = lead.Phone?.replaceAll('^0-9', '');

        if (String.isNotBlank(phone)) {
            phones.add(phone);
        }
    }

    // Query all the contacts that match either a mobile or home phone number from
    // the input "leads"
    List<Contact> contacts = [SELECT Id, Phone FROM Contact WHERE Phone IN :phones];

    // Turn this into a lookup from phone number to the Contact's ID
    Map<String, Id> contactIdsByPhoneNumber = new Map<String, Contact>();

    for (Contact contact : contacts) {
        // This assumes contacts have unique phone numbers; if there are duplicates
        // then the last one matching is stored
        contactIdsByPhoneNumber.put(contact.Phone, contact.Id);
    }

    // Now generate the results in the same order as the inputs    
    List<String> results = new List<String>();
    
    for (MethodInputs lead : leads) {
        // Find the contact ID for the input lead by Phone or MobilePhone number
        Id contactId = contactIdsByPhoneNumber.get(lead.Phone);

        if (contactId == null) {
            contactId = contactIdsByPhoneNumber.get(lead.MobilePhone);
        }

        // This may be null if there is no contact for this lead's Phone or
        // MobilePhone number
        results.add(contactId);
    }
    
    return results;
}
2
  • Thanks, @Phil W! I had several Contact phone fields to check against, so with minor tweaks the code you provided works perfectly.
    – JaredC
    Mar 22 at 20:27
  • Glad it helped. Just so long as it makes sense and you can understand each step.
    – Phil W
    Mar 22 at 21:42

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.