1

My code works everywhere except in a particular client sandbox. It basically sends an email on insert of a record.

Pseudo-code in PKG A

trigger on after-insert of recordX
    Messaging.sendEmail(email)

Offending code in sandbox

insert new RecordX

The error in this specific sandbox is:

System.EmailException: SendEmail failed. First exception on row 0; first error: UNKNOWN_EXCEPTION, You have uncommitted work pending. Please commit or rollback before calling out: []

Here are the last few lines of the logs:

16:03:13.395 (431553895)|VARIABLE_SCOPE_BEGIN|[39]|mail|Messaging.SingleEmailMessage|true|false
16:03:13.395 (431641669)|VARIABLE_ASSIGNMENT|[39]|mail|"common.api.soap.wsdl.SingleEmailMessage@51484da"|0x1d47ef24
16:03:13.395 (431647105)|STATEMENT_EXECUTE|[40]
16:03:13.395 (431662684)|VARIABLE_SCOPE_BEGIN|[9]|email|Messaging.SingleEmailMessage|true|false
16:03:13.395 (431707578)|VARIABLE_ASSIGNMENT|[9]|email|"common.api.soap.wsdl.SingleEmailMessage@51484da"|0x1d47ef24
16:03:13.395 (431712353)|STATEMENT_EXECUTE|[10]
16:03:13.395 (431761721)|STATEMENT_EXECUTE|[11]
16:03:13.395 (431812208)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:4
16:03:13.395 (431836983)|HEAP_ALLOCATE|[4]|Bytes:5
16:03:13.395 (431853427)|VARIABLE_ASSIGNMENT|[4]|rt|null|
16:03:13.395 (431858129)|STATEMENT_EXECUTE|[14]
16:03:13.395 (431859506)|STATEMENT_EXECUTE|[14]
16:03:13.395 (431887361)|STATEMENT_EXECUTE|[14]
16:03:13.395 (431942623)|HEAP_ALLOCATE|[EXTERNAL]|Bytes:8
16:03:13.395 (585405722)|EXCEPTION_THROWN|[14]|System.EmailException: SendEmail failed. First exception on row 0; first error: UNKNOWN_EXCEPTION, You have uncommitted work pending. Please commit or rollback before calling out: []
16:03:13.395 (586030977)|HEAP_ALLOCATE|[14]|Bytes:163
16:03:13.395 (586074343)|VARIABLE_SCOPE_BEGIN|[16]|e|System.EmailException|true|false
16:03:13.395 (586151005)|VARIABLE_ASSIGNMENT|[16]|e|"common.apex.methods.MessagingStaticMethods$EmailExecutionException: SendEmail failed. First exception on row 0; first error: UNKNOWN_EXCEPTION, You have uncommitted work pending. Please commit or rollback before calling out: []"|0x6406da32
16:03:13.395 (586159529)|STATEMENT_EXECUTE|[16]
16:03:13.395 (586198500)|HEAP_ALLOCATE|[17]|Bytes:159
16:03:13.395 (586206818)|HEAP_ALLOCATE|[17]|Bytes:27
16:03:13.395 (586235313)|STATEMENT_EXECUTE|[17]
16:03:13.395 (586285305)|FATAL_ERROR|System.EmailException: SendEmail failed. First exception on row 0; first error: UNKNOWN_EXCEPTION, You have uncommitted work pending. Please commit or rollback before calling out: []

Trigger.PKGA.TriggerX: line 14, column 1
16:03:13.395 (586302271)|FATAL_ERROR|System.EmailException: SendEmail failed. First exception on row 0; first error: UNKNOWN_EXCEPTION, You have uncommitted work pending. Please commit or rollback before calling out: []

While this KB article seems to address the issue (albeit indirectly, as I am not doing a callout here) I don't understand the reason for the discrepancy.

Note that sending a simple email through Execute Anonymous works fine.

  • Looks like there is callout in between transaction. – Ashwani Jan 19 '16 at 5:36
  • Logs are not showing any callouts. It is breaking right when SendEmail is called.. Also an update here: this issue is only happening in one particular sandbox. It works fine in other sandboxes. So it can't be Spring '16. – Mossi Jan 19 '16 at 21:19
2

The email that was being sent was based on a VF template with an attachment component whose controller called getContent() on a SF record. The following Critical Update connects the dots:

“PageReference getContent() and getContentAsPDF() Methods Behave as Callouts” Critical Update Postponed

This update had been activated in this particular sandbox instance, which explains why no other org experienced the issue.

0

Typically the reason for this error is where a DML statement is performed before a callout. In your case it looks like sending the email is counted as a callout.

You have two options that I see:

  1. Send your email and then insert recordX
  2. Insert recordX, then make sendEmailViaTrigger() a future / Queueable implementation. Making this method asynchronous will mean that it counts as a separate transaction, avoiding the error.

More info on future methods here and more info on the Queueable interface here .

HTH

  • Why would it be counted as a callout in one sandbox but not for others? More importantly why would SendEmail count as a callout?! Btw I am only looking for the reason for the discrepancy not the solution/workaround. Thanks! – Mossi Jan 19 '16 at 23:58
  • Without your code it's hard to say, but if you have multiple triggers on a single object then possibly the order of trigger execution is different on that single sandbox. – Davin Casey Jan 20 '16 at 7:58
  • There are no other triggers on insert of recordX. The sequence of events is exactly: insert recordX > trigger on recordX runs and calls SendEmail. According to the debug logs nothing else is happening in between.. – Mossi Jan 21 '16 at 20:40
  • Can you post all the code in question? – Davin Casey Jan 22 '16 at 9:36

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.