Did something change recently with the SingleEmail methods that prevents using setToAddresses() when a template is used?


I need to send an email to a user based and pass in the related record. However, you can't set targetObjectId to a user id if whatId has been set.

There used to be two known workarounds. First, to create a contact with the desired email address and use that for targetObjectId. Second, don't set targetObjectId and instead set toAddresses to the target user's email (see this answer). However, the docs seem to state this is no longer possible.

setToAddresses(String[]) Optional. A list of email addresses to which you are sending the email. The maximum number of email addresses allowed is 100. This argument is allowed only when a template is not used. via apex docs

I'm really hoping to avoid creating a dummy contact for this since we have a lot of triggers on that object. Am I taking crazy pills and it was never actually possible to use toAddresses with templateId or is this a recent change? If it's a recent change is there any other workaround?

Desired Usage

public static void send(Id recordId, Id templateId, String toAddress) {
    Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
    email.setToAddresses(new String[] { toAddress });
    Messaging.sendEmail(new Messaging.SingleEmailMessage[] { email });

Resulting Error Message

System.EmailException: SendEmail failed. First exception on row 0; first error: REQUIRED_FIELD_MISSING, Missing targetObjectId with template: []


Using Newly introduced method setTreatTargetObjectAsRecipient() in Winter 16, you can send email message to any email address.

    Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
    email.setToAddresses(new String[] { toAddress });   

    //Set current user as target object 

    //This method would make sure email will not be sent to user
    Messaging.sendEmail(new Messaging.SingleEmailMessage[] { email });
| improve this answer | |
  • Ishwar, might be worth mentioning which Release and API version this new method is available in. – Dave Humm Jul 4 '16 at 8:50

I am fairly certain that you have always been required to use a templateId and targetObjectId in tandem. All of my code that sends an email using a template requires a contact to be associated to the email, and I am fairly certain that this was because the system required this condition when I wrote the code a few years back. The problem is that without a targetObjectId, the template can't merge contact fields correctly, so they probably made this restriction intentionally.

You don't need to use a contact, though, as leads are also acceptable targets. If your leads are less burdened than contacts are, you might simply choose to create a new lead instead (but then you can't set a "what id", such as an opportunity). In any event, you could probably just patch your triggers to ignore any contacts created when a certain flag is true, and use a @future method to (hard) delete the contact once the email has been sent. Of course, if you have installed packages, this may not be feasible.

| improve this answer | |
  • thanks for the confirmation, still don't understand why they haven't fixed it to where you can user users and the template. They're fine with you not setting whatId with a template, but enforcing the user piece is strange. Big hole :( – Ralph Callaway Dec 31 '13 at 18:40
  • not to mention confusing seeing as workflows alerts have no problems with users as targets – Ralph Callaway Dec 31 '13 at 18:40

I think it has always been that way. One work around could be to create a temporary contact and use that to send the email. (Haven't tested it, though)

| improve this answer | |
  • @sfdcfox What if we want to use a template that is not based on contact/lead object -- n due to this targetObjectId -referring only user/lead, we are unable to establish a context for this template we want? What would be your suggestion in such case. – user10727 Jan 18 '15 at 16:23

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.