Can any one help me out with this error .

1)When im using mail.setTargetObjectId(c.CustomerSignedId); the system start throwing a error .

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

2)When im using mail.setTargetObjectId('00538000004bjrA'); the system start throwing a error .

SendEmail failed. First exception on row 0; first error: INVALID_ID_FIELD, WhatId is not available for sending emails to UserIds.: [whatId, 8004B000000Qmzi]

3)When i use mail.setTargetObjectId(c.OwnerId); ,

i get the email but the merge fields value are not getting displayed

Here is the Code which im using the Batch Class :

global void execute(Database.BatchableContext bc, List < Contract > recs) {
        List < Messaging.SingleEmailMessage > mailList = new List < Messaging.SingleEmailMessage > ();
        for (Contract c: recs) {
            if (c.Contact_Email__c != null) {
                List < String > toAddresses = new List < String > ();
                List < String > CcAddresses = new List < String > ();
                Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
               // toAddresses.add(c.Account.Owner.Manager.Email);

Any Suggestion very much appreciated.

  • This may be because of that user don't have permission too read those fields you are not getting in email... Commented Apr 21, 2016 at 10:24
  • itzmukeshy7 :Thanks for your reply.Iam a sys admin.I do have access for all.When i created the template and tested it with send test ,i got the email as expected.When i used the template id in code and executed ,i get the email but the merge fields value are not getting displayed.Any suggestion. Commented Apr 21, 2016 at 10:25
  • I'm not saying that you are a admin or not i'm saying that the object you are passing to template that have access to data rendered by the template... Commented Apr 21, 2016 at 10:28
  • what kind of field is CustomerSignedId? Lookup to Contact or User? Commented Apr 21, 2016 at 10:46
  • @Guy:CustomerSigned is a standard field in contract object which is lookup(Contact). Commented Apr 21, 2016 at 10:49

3 Answers 3


I see several things happening here.

First, there's an issue with the following:


Optional. A list of carbon copy (CC) addresses. The maximum allowed is 25. This argument is allowed only when a template is NOT used.

As you're using a template, this obviously causing an issue for you.

Next, it sounds as though you want your email to be about your customer contact, in which case, the contact needs to be the Id you use for:


Required if using a template, optional otherwise. The ID of the contact, lead, or user to which the email will be sent. The ID you specify sets the context and ensures that merge fields in the template contain the correct data.

You'll note that the above can't be anything other than a one of those three.

For your purposes, you may need to also use this field setting it to false:


Optional. If set to true, the targetObjectId (a contact, lead, or user) is the recipient of the email. If set to false, the targetObjectId is supplied as the WhoId field for template rendering but isn’t a recipient of the email. The default is true.


If you specify a contact for the targetObjectId field, you can specify an optional whatId as well. This helps to further ensure that merge fields in the template contain the correct data.

Since you had wanted to reference c.CustomerSignedId, it sounds as though you really want to reference some kind of contract or document that's been signed, if so, that's probably what needs to go here for the WhatId.

The value for the WhatId must be one of the following types:

  • Account
  • Asset
  • Campaign
  • Case
  • Contract
  • Opportunity
  • Order
  • Product
  • Solution
  • Custom

If you want to include yourself as the admin, instead of adding yourself to the cc's or BCC's, you can always just add yourself to the list of email address your sending the email to. However, with a template, you can't do it using any of the below:


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.

Instead, using a template, if you want to use set for the addresses, you're going to need to use either an HTML or text email body tag:


Optional. The HTML version of the email, specified by the sender. The value is encoded according to the specification associated with the organization. You must specify a value for setTemplateId, setHtmlBody, or setPlainTextBody. Or, you can define both setHtmlBody and setPlainTextBody. setTreatBodiesAsTemplate(treatAsTemplate)

After doing the above, I suggest you try using this tag if you have merge fields you want to use. It's possible it may work for you without throwing an error. I've not tested it to see, but it's worth a try.


Optional. If set to true, the subject, plain text, and HTML text bodies of the email are treated as template data.

For more on all the above, see SingleEmailMessage Methods

  • 1
    setting setTreatTargetObjectAsRecipient(true) worked for me. Thanks @crmprogdev
    – MnZ
    Commented Aug 19, 2016 at 9:56
  • Using setTreatBodiesAsTemplate(true) works for the merge fields but not all the HTML rendered correctly. The logo we have in our letterhead is missing and there are a few of these "]]>" strings lying around which are present in the HTMl value of the template. Commented May 18, 2021 at 17:39

Email Template id used in the code :

When we are using the "Templateid" ..make sure we use only the "TargetObjectId" and SetToAddress not be used.WhatID is used as an optionally

It was an ideally mistake which i was using in the code both the targeobjectid and setToAddress.

global void execute(Database.BatchableContext bc, List < Contract >
     recs) {
            List < Messaging.SingleEmailMessage > mailList = new List < Messaging.SingleEmailMessage > ();
            for (Contract c: recs) {
                if (c.Contact_Email__c != null) {

                     Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
                   mail.setTemplateId('00X4B000000M3go');//Give the Email Template is
                    mail.setTargetObjectId(c.Contact__r.id);//Contact/lead or userid to be specified.

                    mail.setWhatId(c.Id);//can be used optionally


This code below is working for me. I'm calling it from a custom Lightning Component and referencing a Custom Metadata Type to store some of the settings (ie- Template Id, Org-wide Address, Send To, etc). I also added code to attach Files, which are passed from a lightning:fileUpload component I'm using, but you could modify/remove that part if not needed.

@crmprogdev - Your post was very helpful, but I have one correction. I'm using a Template and also able to use the setToAddresses and setCcAddresses. See code below:

Called from Lightning Component controller, but remove @AuraEnabled to use elsewhere

public static void sendEmailWithFiles(List<String> fileIds, Account acc) {
    // Create EmailMessage List and individual record
    List<Messaging.SingleEmailMessage> emailList =  new List<Messaging.SingleEmailMessage>();     
    Messaging.SingleEmailMessage em = new Messaging.SingleEmailMessage();

    // Get Custom Metadata Type settings
    myCustomSetting__mdt emailMeta = [SELECT EmailTemplateId__c, OrgWideAddressId__c, Send_To_Email__c,
                               CC_Email__c, ContactId__c FROM myCustomSetting__mdt
                               WHERE DeveloperName = 'MyEmailSettings' LIMIT 1];

    // Email Template Id + Org-Wide Address

    // Account record; ContactId required when using an Account + Template
    // Can use a generic contact. Will not email the contact due to 3rd line below

    // Recipient email addresses
    List<String> sendToList = new List<String>();

    // CC email addresses
    List<String> ccList = new List<String>();

    // Attach files from the related Content Version data
    List<Messaging.EmailFileAttachment> filesToAttach = new List<Messaging.EmailFileAttachment>();
    List<ContentVersion> contentList = [SELECT Id, ContentDocumentId, ContentBodyId,
                            Title, FileExtension, isLatest, VersionData
                            FROM ContentVersion
                            WHERE ContentDocumentId IN:fileIds AND isLatest = true];

    if (!contentList.isEmpty()) {
        for (ContentVersion cv : contentList) {
            if (cv.Title != null && cv.VersionData != null && cv.FileExtension != null) {
                Messaging.EmailFileAttachment emFile = new Messaging.EmailFileAttachment();
                emFile.filename = cv.Title + '.' + cv.FileExtension;
                emFile.body = cv.VersionData;

    // Add email to the master list and send

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .