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

System.LimitException: Too many Email Invocations: 11

My use case:

  • Sending demand letters to customers - single and mass
  • Custom objects: Payment_Schedule__c contains the amount to be paid/already paid amounts. Demand_Letter__c contains the body of the Demand Letter sent as well as its PDF attachment. Both are linked to Opportunity
  • User will send a Demand Letter by clicking on New button in Opportunity's related list - Single
  • User will send Demand Letter by selecting Opportunities and clicking Create Demand Letter button on Opportunity list view - Mass

Single sending works absolutely fine. Steps invlolved: 1. Create demand letter (name,Page1 content,Page2 content). 2. Save. 3. After saving on clicking Generate PDF button will display the contents - page1,page2 as well as pending payment in 3rd page. 4. If it looks fine, then send an email by attaching the pdf by clicking on Send Email button. DONE.


I am encountering problem with mass email. When there are more than 10 recipients(or Opportunities) selected, I receive System.LimitException: Too many Email Invocations: 11. Below is my code:


    public void sendAction() {
        try {
            showSendBtn = false;
            rtId = [select Id,name from RecordType where name='Demand Letter_After Sending' and SObjectType='Demand_Letter_Repository__c' limit 1].Id;
            if(! mass) {
                System.debug('### (DemandLetterEmailController) SINGLE. sendAction');
                dlObj.RecordTypeId = rtId;
                update dlObj;
            else {
                System.debug('### (DemandLetterEmailController) MASS. sendAction');
                System.debug('### (DemandLetterEmailController) lstDLR.size-inside sendAction: ' + lstDLR.size());
                //System.debug('### (DemandLetterEmailController) lstDLR-inside sendAction: ' + lstDLR);
                arrId.clear(); // arrId contains the opp ids. Hence clear all before re-using it for storing DLR's ids
                for(Demand_Letter_Repository__c dObj : lstDLR) {
                lstDLR = [select Name,Opportunity__c,Page1__c,Page2__c,To__c,
                    MassEmail__c,RecordTypeId from Demand_Letter_Repository__c 
                    where Id IN: arrId];
                System.debug('### (DemandLetterEmailController) after select.lstDLR.size-inside sendAction: ' + lstDLR.size());    
                for(Demand_Letter_Repository__c d : lstDLR) {
                    oId = String.valueOf(d.Opportunity__c).subString(0,15);
                    dId = String.valueOf(d.Id).subString(0,15);
                    //System.debug('### (DemandLetterEmailController) d-for loop: ' + d);
                    if(d.To__c !=null)
                        toAddresses = new String[]  { d.To__c } ;
                        toAddresses = null;
                    if(d.CC__c !=null) {
                        if(d.Opportunity__r.HFI__c !=null) {
                            System.debug('### (DemandLetterEmailController) inside d.Opportunity__r.HFI__c !=null');
                            if(d.Opportunity__r.HFI__r.Email__c != null) {
                                if(! d.CC__c.contains(d.Opportunity__r.HFI__r.Email__c)) {
                                    System.debug('### (DemandLetterEmailController)if ! d.CC__c.contains(d.Opportunity__r.HFI__r.Email__c)');
                                    d.CC__c = d.CC__c + ',' + d.Opportunity__r.HFI__r.Email__c;
                        ccAddresses = d.CC__c.split(',');
                        ccAddresses = null;
                    d.MassEmail__c = true;
                    d.RecordTypeId = rtId;
                update lstDLR;
            insert lstAtt;
            insert lstTask;
        catch(Exception e) {
            System.debug('### (DemandLetterEmailController) Exception-sendAction: ' + e.getMessage());
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL,e.getMessage()));            
    private void sendAndAttach(Demand_Letter_Repository__c dlr) {
        mail = new Messaging.SingleEmailMessage();
        System.debug('### (DemandLetterEmailController) dlr: ' + dlr);
        System.debug('### (DemandLetterEmailController) dId: ' + dId);
        System.debug('### (DemandLetterEmailController) oId: ' + oId);
        pdf = new PageReference('/apex/DemandLetterPDF?id=' + dId + '&oppId=' + oId + '&type=old');
        System.debug('### (DemandLetterEmailController) pdf: ' + pdf);
        // Take the PDF content
        if(test)  // Just to skip if called from test method
            b = null;
            b = pdf.getContent();
        //Attach to Progress-**bleep**-Demand Letter Repository record
        lstAtt.add(new Attachment(parentId =dlr.Id,name=dlr.Name + '.pdf',body=b,OwnerId=dlr.OwnerId));
        System.debug('### (DemandLetterEmailController) lstAtt: ' + lstAtt);
        System.debug('### (DemandLetterEmailController) toAddresses: ' + toAddresses);
        if(toAddresses== null) {
            ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL,'Error while sending email - No TO address specified. *** A task has been created to take hard copy ***'));
            lstTask.add(new Task(Subject='Send Hard Copy',ActivityDate=System.Today(),Status='Not Started',
                                 WhatId=dlr.Id,Description='The customer does not have email specified. Send hard copy.',
                                 OwnerId = dlr.OwnerId,ReminderDateTime=System.Now(),IsReminderSet=true));
        // Create the email attachment  
        efa = new Messaging.EmailFileAttachment();
        //System.debug('### (DemandLetterEmailController) toAddresses: ' + toAddresses);
        mail.setPlainTextBody('Find attached demand letter.');
        mail.setHtmlBody('<div align="center"><h2><b>Demand Note</b></h2></div>'+
                     'Dear Sir/Madam,<br/><br/> Find attached demand letter.<br/><br/><br/>' +
                     'Regards,<br/>For Brigade Group.<br/>' +
                     'Date:' + String.valueOf(,10));
        mail.setFileAttachments(new Messaging.EmailFileAttachment[] {efa});
        System.debug('### (DemandLetterEmailController) mail: ' + mail);
        r = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});
        for(Messaging.sendEmailResult result : r) {
            if(result.isSuccess()) {
                ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.CONFIRM, 'Email Sent Successfully. To: ' + toAddresses + ' Cc: ' + ccAddresses));
                dlr.Sent_Date__c = System.Today();
                ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, 'Error while sending email. To: ' + toAddresses + ' Cc: ' + ccAddresses));
        System.debug('### (DemandLetterEmailController) mail: ' + mail);


Any help would be appreciated.



I have referred the following post but I am looking for simpler solution because of very limited time:


I cannot use @future since I have used getContent method in my class.

Kindly suggest. 

Shashikant SharmaShashikant Sharma

You are using this method sendAndAttach in  below for loop and that is causing you the exception

for(Demand_Letter_Repository__c d : lstDLR) 



Solutions :

1) Create a public property List of Messaging.SingleEmailMessage


Public List<Messaging.SingleEmailMessage> listMail = new List<Messaging.SingleEmailMessage>();


2)in this method sendAndAttach in your class instead of sending mail just add that item to list 

3)When your for loop ends send listMail like 

   Messaging.sendEmail(listMail );


See this example

List<Messaging.SingleEmailMessage> listmail = new List<Messaging.SingleEmailMessage>();
for(User userObj : ListOfMailRecieptentUsers)
   Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
   string body = userObj.Name;  
   mail.setSubject('Mail Subject');


in your case call method sendAndAttach in for loop to add item to list.


Let me know if any issues in it.



I had tried it before its not working.

I get the null pointer exception !!!

12:07:00.216 (1216467000)|SYSTEM_METHOD_ENTRY|[216]|LIST.add(ANY)
12:07:00.216 (1216511000)|EXCEPTION_THROWN|[216]|System.NullPointerException: Attempt to de-reference a null object
12:07:00.216 (1216549000)|SYSTEM_METHOD_EXIT|[216]|LIST.add(ANY)

 Code which causes this is:

         sem.add(mail);                                                                                                                                        if(counter == 10) {
            System.debug('### (DemandLetterEmailController) INSIDE IF counter =10');
            counter = 0;
    private void sendTen(Demand_Letter_Repository__c dlr) {
        System.debug('### (DemandLetterEmailController) sem.size: ' + sem.size());
        r = Messaging.sendEmail(sem);
        for(Messaging.sendEmailResult result : r) {
            if(result.isSuccess()) {
                ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.CONFIRM, 'Email Sent Successfully. To: ' + toAddresses + ' Cc: ' + ccAddresses));
                ApexPages.addMessage(new ApexPages.Message(ApexPages.Severity.FATAL, 'Error while sending email. To: ' + toAddresses + ' Cc: ' + ccAddresses));

 I have initialized the list in the controller : sem = new List<Messaging.SingleEmailMessage> ();


Kindly let me know if you have suggestions.


Does it has to anything with transient keyword? When I declare list as transient I get Null pointer exception as posted above. 

If I dont declare this list as transient then I get Not Serializable: LIST<Messaging.SingleEmailMessage>  error !!!


I found out that eventhough I am initializing the List in constructor, when the control reaches to that line the list is NULL !!!!


So I initialized the list just before entering the for loop. Now it works fine. I am able to send email to more than 10 recipients. But what is the limit for size of this list. Any idea shashikanth?



I'm also facing the same issue.

 Here is my code


String tempEmailId ='';
        List<Messaging.SingleEmailMessage> listmail = new List<Messaging.SingleEmailMessage>();
        if(CR != NULL)
                            List<Contact_Role__c> cRoles= [Select Id,Name,Contact_Name__c, Account__c,Contact_Name__r.Email,Role_Played_New__c From Contact_Role__c WHERE (Role_Played_New__c = 'Role: Key Account Director' ) AND End_Date__c= null AND Account__c = :CR.Account__c ];
                            if(cRoles==null || cRoles.isEmpty())
                               cRoles= [Select Id,Name,Contact_Name__c, Account__c,Contact_Name__r.Email,Role_Played_New__c From Contact_Role__c WHERE ( Role_Played_New__c = 'Role: Relationship Manager') AND End_Date__c= null AND Account__c = :CR.Account__c ];
                            for(Contact_Role__c contactRole :cRoles)
                                                System.debug('<><><><><>Email ID:'+contactRole.Contact_Name__r.Email);

                                                String[] eAddress = new String[]{};
                                                Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                                                mail.setSenderDisplayName('Deloitte-Prudential Salesforce Implementation');
                                                mail.setSubject('Notification for New Client Reference');
                                    tempEmailId = tempEmailId + ';' +contactRole.Contact_Name__r.Email;
        catch(Exception e)
            System.debug('Inside email() :'+e.getMessage());


Appreciate your help.



Jerun JoseJerun Jose

Hi Karthik,


Could you try checking the size of the listMail before sending the emails. I have a doubt if the list is empty.




Jerun Jose


Hi Jerun,

Its not working after implementing this   getting the same error .Any other thoughts .

List size is displaying 1 , which is not empty for me.




Hi ,


Please check below link, this blog will help you to resolve this.



I followed the similar approach and still getting the same error.



public void sendEmail()

// Collection to capture list of users who haven't logged in system for past 60dys.
List<User> usersNotLoginFor60Days = new List<User> ([Select id,name,,email From User Where Exclude_from_HR_Feed__c != True And IsActive = True And HR_Feed_Flag__c = False and lastlogindate < LAST_N_DAYS:60 and id = '005E0000000EFXz']);
List<Messaging.SingleEmailMessage> listmail = new List<Messaging.SingleEmailMessage>();
//String[] lstid = new String[]{};
String[] eAddress = new String[]{};
String[] Name = new String[]{};

//String uid = '';

for (User u : usersNotLoginFor60Days)
      //  Id[] targetObjectIds1 = new Id[] {};
      //Id[] whatIds = new Id[] {};
      //  lstid.add(;
       // uid =;
    //final String template = 'User Deactivation';
    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
    //mail.setTemplateId([select Id from EmailTemplate where Name = :template].Id);
  //mail.setSubject('Salesforce Deactivation Mail');
  //  mail.setTargetObjectId(uid);
    mail.setSenderDisplayName('Salesforce Support');
    mail.setHtmlBody('<html>' + '<h4>'+'Dear' +Name+ ','+'</h4>' + '<br/>'+'<br/>' +'<body align="center">'+
    'You are receiving this email because your Salesforce account has been deactivated due to inactivity in the last 60 days.'+
    '<br/>'+'If you feel that this deactivation has occured in error, please have your manager submit an IT Application request to'+
    '<br/>'+'have your salesforce account reactivated.'+'<br/>'+'<br/>' +'To Submit the IT Application request, please visit the website:'+
    '<br/>' +'<a href="">Hyperlink Code</a>'+'<br/>'+'From the Application list, please select "Salesforce PRM".'+'<body/>'+
    '<br/>' +'Sincerely,'+'<br/>'+'CNA Salesforce Team'+'<html/>');
    //system.debug('mail size'+mail.size());

    //Messaging.sendEmail(new Messaging.SingleEmailMessage[]{mail}); 


Please suggest how to resolve.


thank you Shashikant Sharma. it saved my time.