I have post install script that is suppose to create records belonging to a certain custom object and all other custom obj records related to it.

In my onInstall method I am querying if the current org contains data belong to that custom obj and if it does not then it creates the above mentioned data.

Something like this:

 global void onInstall(InstallContext context) {
       List<CustomObj__c> objList = [select Id from CustomObj__c];

       if(objList != null && !Test.isRunningTest()) {

 private void createRecordsForCustomObj() {
       //this method creates data for custom obj
       CustomObj__c obj = new CustomObj__c();
       obj.Field1__c = 'value';
       obj.Field2__c = 'value';
       insert obj;

And so on it would create other related records. My problem is, the post install script wont run. On installation it does not give any errors (package failed or anything else). The package installs smoothly but when I go and check if the data was created for that CustomObj__c, it is not.

Is there something wrong in my code or am I suppose to do some setting on the new org before installing a package?

Oh FYI: I am creating a Beta package, dont know if that factor comes into play.



Make sure you have specified the class name which you want to run on Post install of the package into the Post Script Install field in the package detail page(In the packaging org).

This field is a lookup of apex classes and you can add this by clicking on the edit of package detail page. You can specify your class as public or global but you must not specify with "with sharing" attribute.

For more information about installHandler interface you can refer to this blog post.

| improve this answer | |

Make sure your class is not defined with sharing. That causes problems with the post install script running in a weird user level.

| improve this answer | |

This is an old question and i'm not sure you are still looking for an answer or not.I just thought i can provide some more information here.

It's for the managed packages- We generally use post install script to take care of the fresh install as well as to upgrade over an old install as well.

By following way we can check if our install is fresh one or an upgrade:

global void onInstall(InstallContext context) {
    //if this is a fresh install
    if(context.previousVersion() == null) {
    //or we are upgrading over a previous version
    else if(context.previousVersion().compareTo(new Version(1,0)) == 0) {

so you don't have to check if there are records there for the custom object, just if you want to insert the records on fresh install put them in the first block otherwise if it is upgrade update them in the second(If you want).

This will work for the beta as well.

FYI: Beta versions can not be upgraded.

For more information on post install script check this link

| improve this answer | |
  • 1
    Thanks Mr. Frodo. I had a beta package and that's what the issue was. We create new beta packages and give them to the test team to install in their sandbox and test. The custom obj creation was one of the test cases. But thanks for the answer and for keeping the middle earth safe by destroying the ring..that was one hell of a journey. – codeinprogress May 1 '16 at 15:10

Make sure your class implements the InstallHandler interface as so:

global class PostInstallScript implements InstallHandler {

Make sure you have actually specified the class as your post install script in your package settings before uploading the next version.

| improve this answer | |
  • Thats what I did. But I just found out that we cannot have post install script on an unmanaged package. So I ran the code manually from the dev console. – codeinprogress Jan 13 '16 at 10:54
  • Ah, that would explain it. I didn't realise you were developing an unmanaged package. – Davin Casey Jan 13 '16 at 11:20

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.