15

I am currently working in a Config-Only sandbox. I have a unit test that is continually failing with the following error message:

System.EmailException: SendEmail failed. First exception on row 0; first error: NO_MASS_MAIL_PERMISSION, Single email is not enabled for your organization or profile. Single email must be enabled for you to use this feature.: []

The interesting thing is that this unit test passes just fine in production. The unit test is for a batchable class. The error is occurring in the finish method on the Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail }); call. The finish method is:

global void finish(Database.BatchableContext bc) {
    AsyncApexJob a = [
        Select Id, Status, NumberOfErrors, JobItemsProcessed, TotalJobItems, CreatedBy.Email
        From AsyncApexJob
        Where Id = :bc.getJobId()
    ];

    // Send an email to the Apex job's submitter notifying of job completion.
    Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
    String[] toAddresses = new String[] {a.CreatedBy.Email};
    mail.setToAddresses(toAddresses);
    mail.setSubject('Batch job complete with status: ' + a.Status);        
    String body = 'Batch job completed.';
    body += '\nThe batch job processed ' + a.TotalJobItems + ' batches with '+ a.NumberOfErrors + ' failures.';
    body += '\nJob Results: ' + a.Id;
    mail.setPlainTextBody(body);
    Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
}

I recently refreshed the sandbox from production and made no permission changes, so I have no idea why one org would be failing while the other is working just fine. The user I am attempting to run this class with is a System Administrator. The System Administrator profile has the Mass Email and Send Email permission selected. Has anyone run into an error like this before?

Saariko
  • 5,610
  • 13
  • 75
  • 165
Jesse Altman
  • 19,718
  • 10
  • 58
  • 103
  • This is really odd behavior since everything looks right, can you post your test class/method to see if I can duplicate this error at all? – jonnybro Feb 26 '13 at 22:38

2 Answers2

22

Have you checked the "Access to Send Email" option under Administration Setup - Email Administration - Deliverability? It's new feature in Spring 13.

Kevin Lam
  • 699
  • 4
  • 9
  • 3
    This was it! I have no idea how this happened (I would assume a sandbox refresh would copy that value over, but the prod system has All Email selected while the sandbox was System Email Only. Changing that value to match prod got the tests passing. Awesome work! Thanks! – Jesse Altman Feb 27 '13 at 13:12
  • 2
    Sandboxes created since Spring '13 default to "System Email Only" which I believe is intended to stop you from inadvertently sending out messages from your test system. – Doug B May 09 '13 at 08:10
  • 1
    note also that testmethods do not send emails (which of course, is good) even if All Email is set. – cropredy Jun 15 '13 at 00:54
  • for the record, all refreshed sandboxes are set to System Email only : https://help.salesforce.com/HTViewSolution?id=000002868&language=en_US – Samuel De Rycke Oct 02 '13 at 13:46
  • Have you checked the "Access to Send Email" option under Administration Setup - Email Administration - Deliverability? It's new feature in Spring 13. Tried the above. It helped –  Aug 03 '14 at 16:35
  • Is there a way to check if this setting is on in APEX to prevent Messaging.sendEmail() call? Trying to prevent unit test & deployments from failing and don't see the point if someone can break unit testing with a setting that is technically unrelated.. the email "would" have been successful, and if the setting was on it would have verified that without sending the email anyways, so why cause an error here. – Xtremefaith Jul 27 '18 at 05:54
7

(Copying this answer from another question)

In Summer '14, (version 31.0), there is a new field available on the Organization object.

select Id, IsSandbox from Organization limit 1

From the release notes under New and Change Objects:

The Organization object has the following new read-only fields.

  • InstanceName
  • IsSandbox

You can for example create a static method that other classes can use like this:

public static Boolean runningInASandbox() {
  return [SELECT Id, IsSandbox FROM Organization LIMIT 1].IsSandbox;
}

You can then call that as a Boolean value:

if (!runningInASandbox()) {
  Messaging.SingleEmailMessage msg = new Messaging.SingleEmailMessage();
  msg.setSubject('An email');
  msg.setToAddresses(new List<String>{siteAdmin.Email});
  msg.setPlainTextBody('A message');
  Messaging.sendEmail(new List<Messaging.SingleEmailMessage>{msg});
}
abd3721
  • 2,152
  • 1
  • 20
  • 36