Error in post-install HTTP request

I’m developing a package with a post-install script.
The script makes a HTTP request to my webserver, or sends me an email if an error occured.

Every time the script is run, I receive this error:

System.CalloutException: You have uncommitted work pending. Please commit or rollback before calling out

Here’s the script. I have tried deleting the “sendEmail” method, thinking that it may be the problem. The problem is that without it I don’t really have a way to know what went wrong (and the request still isn’t made):

public class PiplInstallationNotify implements InstallHandler {

        public static void onInstall(InstallContext ctx){
        try {
            User activeUser = [Select Email From User where Id = : ctx.installerId() limit 1];
            String userEmail = activeUser.Email;
            String orgId = ctx.organizationId();

            HttpRequest req = new HttpRequest();
            HttpResponse res = new HttpResponse();
            Http http = new Http();


            //these parts of the POST you may want to customize
            req.setHeader('Content-Type', 'application/x-www-form-urlencoded');  
            res = http.send(req);
            try {
            } catch(System.CalloutException e) {
                System.debug('Callout error: '+ e);
                sendEmail('Callout error: '+ e);
        } catch(Exception ex){
           sendEmail('Message : ' + ex.getMessage() + 'Line no : ' + ex.getLineNumber() + ' getStackTraceString ' + ex.getStackTraceString() + '' + ex.getCause());

    @future (callout=true)
    public static void sendEmail(String message){
        List<String> listEmailMembers;
        Messaging.SingleEmailMessage emailTobeSent = new Messaging.SingleEmailMessage();
        listEmailMembers = new List<String>();
        emailTobeSent.setSubject('Email message from Salesforce script');
        Messaging.SendEmailResult [] r1 = Messaging.sendEmail(new Messaging.SingleEmailMessage[] {emailTobeSent});

    static void testInstallScript() {
      PiplInstallationNotify postinstall = new PiplInstallationNotify();
      Test.testInstall(postinstall, null);
      Test.testInstall(postinstall, new Version(1,0), true);


InstallHandler context cannot perform any synchronous callouts at all.

It can only perform callouts using an async operation. The callout occurs after the script is run and the install is complete and committed.

If the package install fails, nothing will escape the transaction: no futures, no callouts, no emails. The good news is that any managed released package whose production install fails, for any reason, will automatically send you an error email. It goes to the user selected on the field: Notify on Apex Error.

Source : Link , Question Author : Josh Liberty , Answer Author : Matt and Neil

Leave a Comment