As we have used Async operations (Future and Queueable) very heavily in our codebase. Thus for doing callouts from trigger, I started using Platform Events + Flow.
So from Trigger a PE will be raised :
Integration_With_External_System__e externalSystem = new Integration_With_External_System__e();
externalSystem.External_System__c = 'POMS';
externalSystem.JSON_Request__c = JSON.serialize(inboundTaskMap.keySet());
Database.SaveResult saveResult = EventBus.publish(externalSystem);
ExceptionHandler.logInfo('sertfhrtsh', 'sergergh', '', '', 'High', null, JSON.serialize(inboundTaskMap.keySet()) + '----------' + String.valueOf(saveResult.getId()));
// More code from trigger
After which the flow will listen to it and then process it (Callout) Something like below:
public without sharing class SendExternalAPIRequestPE {
@InvocableMethod(Label='test callout' Callout=true)
public static void fireAPIRequest(List<String> strings){
List<ARecord__c> aRecords = new List<ARecord__c>();
System.debug('strings -> '+strings.size());
try{
for (Integer i = 0; i < strings.size(); i++) {
Http h = new Http();
HttpRequest req = new HttpRequest();
req.setEndpoint('https://jsonplaceholder.typicode.com/users');
req.setMethod('GET');
HttpResponse res = h.send(req); // Throws exception here randomly.
ARecord__c aRecord = new ARecord__c();
aRecord.testMe__c = String.valueOf(res.getStatusCode());
aRecord.Name = 'Proper Response '+i;
aRecords.add(aRecord);
}
} catch(Exception objException){
ARecord__c aRecord = new ARecord__c();
aRecord.testMe__c = objException.getMessage();
aRecord.Name = 'Exception';
insert aRecord;
} finally {
insert aRecords;
}
}
}
These all work fine. But sometimes, I see exception being logged as You have uncommitted work pending. Please commit or rollback before calling out. Which is strange because I have configured PE to be published only after commit.
So not sure which commit is still pending. As SF identified a commit is pending, is there a way to log which commit is pending here. Or whats is the issue here?
NOTE: This exception happens randomly, I can say 2 out of every 10 request shows this exception.
I debugged it more.
I added some debuglogs just after fireAPIRequest.
debugLog = debugLog + 'Governor Limits -> '+ LimitUtils.getRemainingDMLStatement() +' -> '+ LimitUtils.getRemainingCallouts() + '\n';
And strangely for most of the executions its printing Governor Limits -> 150 -> 100
But few are getting printed as Governor Limits -> 149 -> 99
The strange part is this is an Invocable method with Callout=true, so technically this should always be a separate transaction. And the debug statement is the first statement in fireAPIRequest not sure what DML and callout already happened?
Flow diagram : Just to show no other operation is done before the apex call.

LimitUtils.getRemainingDMLStatement()as its the first debug statement afterfireAPIRequest. This is a bug in Salesforce. I will attach some evidences in my answer below after some time. – Nagendra Singh May 22 '22 at 04:49runs asynchronously in a separate transactionas per doc. Which does not seem to be true ifLimitUtils.getRemainingDMLStatement()returns less than 150 at the start of the transaction. https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platform_events_subscribe_flow.htm#:~:text=Each%20platform%20event%E2%80%93triggered%20flow,interview%20evaluates%20the%20event%20message. – Nagendra Singh May 22 '22 at 06:41