What else, other than insert/update/upsert/delete, can cause "System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out"? I've search the debug logs multiple times, and there absolutely is not a DML statement executed between the startTest and the failing callout.

Are there any other commands, or perhaps another callout (even though it's only an inquiry), that can cause this? Does anyone know how to get around this problem?

  • 3
    Please share your code and that will take it from a guessing game to a Q&A format.
    – Adrian Larson
    Feb 6, 2017 at 17:30
  • 2
    Do you have any workflows are getting fired which is sending emails? Feb 6, 2017 at 17:35
  • Setting savepoints or rolling back to them, basically any asynchronous calls, there are a great many possibilities here.
    – Adrian Larson
    Feb 6, 2017 at 17:40
  • 2
    Have you read this document, and made sure you followed the rules? All DML must occur before Test.startTest, Test.setMock should be called immediately after Test.startTest, and your callout should be called immediately after that.
    – sfdcfox
    Feb 6, 2017 at 18:14
  • I'd second @SantanuBoral here... Workflow email alerts (even ones which are triggered in before startTest()) will cause this error.
    – NSjonas
    Feb 6, 2017 at 18:49

1 Answer 1


Here is a list of the operations that could possibly count as a DML when executed before a callout:

  • Database methods
    • convertLead
    • delete
    • deleteAsync
    • deleteImmediate
    • emptyRecycleBin
    • executeBatch
    • insert
    • insertAsync
    • insertImmediate
    • merge
    • rollback
    • setSavepoint
    • undelete
    • update
    • updateAsync
    • updateImmediate
    • upsert
  • System methods
    • abortJob
    • enqueueJob
    • movePassword
    • process
    • purgeOldAsyncJobs
    • resetPassword
    • schedule
    • scheduleBatch
    • setPassword
    • submit
  • Messaging methods
    • reserveMassEmailCapacity

Special Case - During tests when object has an email alert

If using API v38 or earlier during test methods when an email alert is set on the object will also produce this error


  • Thanks Adrian. Actually there's one more under messaging, which is the one I was hitting. Here's a discovery: within a test run, the system is looking at the real Limits.getSingleEmailInvocations() and Limits.getLimitSingleEmailInvocations() when trying to send email, even though if you check those values they always return 0 and 10 inside the test, respectively. Since test instances typically only allow 10 emails, this is a serious issue for any code that generates emails. Feb 6, 2017 at 19:06
  • 2
    I've made this post a wiki, in case anything was missed. Feel free to add any methods that are not included already.
    – Adrian Larson
    Feb 6, 2017 at 19:07
  • Thanks for this. After a callout, I was calling a simple Database.executeBatch that contained no explicit DML, inside a class that contained no explicit DML. Took me a day to track this down and (kind of) understand. The basic response of 'Dont do any DML before a Callout' isnt really clear enough for me. Is there any documentation that simply calling methods such as Database.executeBatch will count as a DML?
    – ATA1k
    May 2, 2018 at 22:01

You must log in to answer this question.

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