0

I have the following error when trying to send an email.

System.EmailException: SendEmail failed. First exception on row 0; first >error: UNKNOWN_EXCEPTION, List has no rows for assignment to SObject: []

    List<User> users = [SELECT Name, Email, Id FROM User WHERE Recipient__c = TRUE and isActive = TRUE];
    EmailTemplate et = [SELECT id FROM EmailTemplate WHERE DeveloperName='Advisor'];

    for(User u : users) {
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

        mail.setTargetObjectId(u.Id);
        mail.setSenderDisplayName('Salesforce');
        mail.setUseSignature(false);
        mail.setBccSender(false);
        mail.setSaveAsActivity(false);
        mail.setTemplateId(et.id);

        Messaging.SendEmailResult[] r = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});
    }

The list users contains at least one record and the Emailtemplate is not null.

This is the result of the mail system debug:

(Messaging.SingleEmailMessage[ getBccAddresses=null; getCcAddresses=null; getCharset=null; getEntityAttachments=null; getFileAttachments=null; getHtmlBody=null; getInReplyTo=null; getOptOutPolicy=SEND; getOrgWideEmailAddressId=null; getPlainTextBody=null; getReferences=null; getTargetObjectId=005D0XXXXXXXXXuIAE; getTemplateId=00XD0XXXXXXXXcbMAA; getToAddresses=null; getWhatId=null; isTreatBodiesAsTemplate=false; isTreatTargetObjectAsRecipient=true; isUserMail=true; ])

  • Look at this article, you may end up deleting the question help.salesforce.com/articleView?id=000159853&type=1 – Rao May 17 '17 at 16:30
  • FYI you only get 10 sendEmail invocations in a transaction. You should instantiate the list before your loop, add each element to it inside of the loop, and then send the list once when your loop is done. – Adrian Larson May 17 '17 at 16:32
  • I made both suggested changes and still the same error – Miguel May 17 '17 at 16:43
  • Which line is actually throwing the error? Are you certain you have a User record where Recipient__c is true? – Adrian Larson May 17 '17 at 17:08
  • Please see my answer, that is perfectly working at my DE – Santanu Boral May 17 '17 at 17:22
1

You code is passing empty list.

This is the correct code.

Main change is at this line:Messaging.SendEmailResult[] r = Messaging.sendEmail(mails);

And kept that out of for loop.

For more information, refer sendEmail()

List<User> users = [SELECT Name, Email, Id FROM User WHERE Recipient__c = TRUE and isActive = TRUE];
EmailTemplate et = [SELECT id FROM EmailTemplate WHERE DeveloperName='Advisor'];

List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();

    for(User u : users) 
    {
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

        mail.setTargetObjectId(u.Id);
        mail.setSenderDisplayName('IAM Salesforce');
        mail.setUseSignature(false);
        mail.setBccSender(false);
        mail.setSaveAsActivity(false);
        mail.setTemplateId(et.id);
        mails.add(mail);
    }

    Messaging.SendEmailResult[] r = Messaging.sendEmail(mails);
  • 1
    I think this is likely to work - however, I think that @Miguel somehow triggered some internal error in the Messaging.sendEmail method - perhaps it has some code weaknesses that Salesforce should look at. Of course, your technique is how he should be doing it, but it is interesting all the same. – Caspar Harmer May 17 '17 at 18:31
  • I already made this implementation and still the same error. Thanks – Miguel May 18 '17 at 8:29
0

It is a best practice to get the query results in a list. If a query does not return any rows we get List has no rows for assignment to sobject error. What I think is your code is failing because EmailTemplate query is not returning any rows. You can update code as below :

public static String ADVISOR = 'Advisor';
List<User> users = [
        SELECT Id
             , Email
             , Name 
          FROM User
         WHERE Recipient__c = TRUE
           AND isActive = TRUE
];

List<EmailTemplate> etList = [
        SELECT Id
          FROM EmailTemplate
         WHERE DeveloperName = :ADVISOR
];   

//Check if emailTemplate records exists, if so then only proceed with the implementation
if (!etList.isEmpty()) {
    List<Messaging.SingleEmailMessage> mails = new List<Messaging.SingleEmailMessage>();
    for (User u : users) {
        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();    
        mail.setTargetObjectId(u.Id);
        mail.setSenderDisplayName('Salesforce');
        mail.setUseSignature(false);
        mail.setBccSender(false);
        mail.setSaveAsActivity(false);
        mail.setTemplateId(etList[0].id);//Make sure you have one record for email template where developer name is advisor or you would have to make this more dynamic    
        mails.add(mail);           
    }

    //As @Adrian Larson mentioned you only get 10 sendEmail invocations in a transaction,
    //it is a best practice to add mails in a list and invoke it once
    if (!mails.isEmpty()) {
        Messaging.SendEmailResult[] r = Messaging.sendEmail(mails);
    }
}

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.