[SalesForce] CANNOT_EXECUTE_FLOW_TRIGGER – System.LimitException: Too many query rows: 50001

I have an apex class that was written by a previous SF Admin and I'm trying to understand why it isn't working. From what I can tell, it is supposed to auto-populate the Account Name that is associated the Opportunity that this custom object (Campaign Design Profile) record is being created on. When select the New button to create the custom record on the Opportunity, the Account Name field is not pre-populated when creating the record. I also tried just populating in process builder via a field reference immediate action and that doesn't pre-populate either. This class passes the test in the sandbox, but fails in production:

Error Message System.DmlException: Insert failed. First exception on row 0; first error: UNKNOWN_EXCEPTION, We can't save this record because the “Update Opp with Master CDP & Campaign Type” process failed. Give your Salesforce admin these details. This error occurred when the flow tried to update records: CANNOT_EXECUTE_FLOW_TRIGGER: We can't save this record because the “Requested Dates” process failed.

Give your Salesforce admin these details. This error occurred when the flow tried to update records: LIMIT_EXCEEDED: System.LimitException: Too many query rows: 50001. You can look up ExceptionCode values in the SOAP API Developer Guide.. You can look up ExceptionCode values in the SOAP API Developer Guide.: []

Stack Trace
Class.CampaignDesignProfileTrigger.testCampaignDesignProfileTrigger: line 53, column 1

public with sharing class CampaignDesignProfileTrigger {
    public void updateAccount(List<Campaign_Design_Profile__c> newProfiles){
        //This procedure will update the Account_Name_Ref__c with the
        //Account Id on the related Opportunity.
        Map<Id, Id> oppAccountIds = new Map<Id, Id>();
        List<Id> oppIds = new List<Id>();
        
        //Retrieving the Opportunity Ids for the new records
        for(Campaign_Design_Profile__c p : newProfiles){
            oppIds.add(p.Related_Opportunity__c);
        }
        
        //Populating the oppAccountIds map with the Opp Id/Acct Id for lookup later
        for(Opportunity o : [Select Id, AccountId From Opportunity Where Id in:oppIds]){
            oppAccountIds.put(o.Id, o.AccountId);
        }
        
        for(Campaign_Design_Profile__c p : newProfiles){
            p.Account_Name_Ref__c = oppAccountIds.get(p.Related_Opportunity__c);
        }
    }
    
    static testMethod void testCampaignDesignProfileTrigger(){
        test.startTest();
        //Retrieving Record Types
        List<RecordType> rec_type = [Select Id From RecordType 
            Where IsActive=true And SobjectType = 'Campaign_Design_Profile__c' Limit 1]; 
        //Creating a test Account
        Account acct = new Account(Name='CampaignDesignProfileTest Account');
        insert acct;
        
        //Creating a test Opportunity
        Opportunity opp = new Opportunity(Name='CampaignDesignProfileTest Opportunity', AccountId=acct.Id,
            StageName='Needs Analysis', CloseDate=system.today());
        insert opp;
        
        //Creating a test Campaign Design Profile
        Campaign_Design_Profile__c cdp = new Campaign_Design_Profile__c(Name='CampaignDesignProfileTest cdp',
            Campaign_Type__c='Account Profiling', Related_Opportunity__c=opp.Id);
            cdp.Estimate_Type__c = 'N/A';
            cdp.Volume__c =14.00;
            cdp.of_Hours__c =15.00;
        insert cdp;
        
        test.stopTest();
    }
}

Best Answer

There are at least two issues here.

Actual Functionality of the Class

It doesn't prepopulate the Account field when you click the New button. The trigger doesn't run until you hit Save. On inspection, it looks like it would probably work at that point.

If you want to pre-populate information in a create action in the UI, you need to use a Quick Action or write a Lightning Component or Visualforce Page. You cannot do that with a trigger at all.

Test Functionality

This is a very old class. Inline test methods like that haven't been allowed since API version 28, from Summer '13.

Your stack trace shows line 53, but this class is not 53 lines long. I would guess line 53 is insert cdp, which would make sense. In production, it seems that your trigger is firing a Process and/or Flow ("Update Opp with Master CDP & Campaign Type") such as the one you mentioned creating, and that Flow is running an unbounded query. So the bug technically isn't in this code, and you may be able to fix it by changing the Flow rather than changing the trigger.

However... the Flow shouldn't be able to see all those records, because it should be isolated by test context. I haven't been around long enough to know API 28 and whether there's unique behavior associated with data exposure in a class that old, but I would say the first thing to do is factor this test method out into a real test class annotated with @isTest on API v46 (like all new classes) and run it there.

The second thing to do is review the Flow and figure out why it's running a query so broad as to hit the SOQL limit. If this can trigger that bad behavior pattern, something else can too.

Related Topic