5

When uninstalling a managed package the process fails with the message:

Unable to uninstall package
Component Type: Record Type
Problem: This installed component is referenced by a locally created component. (link to a particular record)

This makes sense, I need to remove the Record Type from local records that are currently using it before uninstalling it.

Can I do this with an apex uninstall script or does it need to be done manually by an admin before attempting the uninstall?

To remove references to the record type manually I mark it as inactive in the admin UI. This may require the additional steps, such as removing the record type as the default from any profiles that are using it.

I can set the RecordTypeId via apex, but I'm not sure what to change it to. I can't see the master record type as a valid value to assign and there may be no other record types for the sObjectType.

Another more drastic approach is to delete all the records that reference that RecordType (and then empty the recycle bin). This is fine for things like Product2 where in my case the records are only applicable to the managed package, but not so great when dealing with Accounts and Contacts.

  • 1
    I wouldn't recommend the deletion approach - unless you can hard delete them...since if you go over the 5000 limit, they go into a nether world where you can't see them in the recycle bin but they aren't actually considered deleted, so you still have to wait for SF to fully delete them before the reference is considered deleted (which can take 24-48 hours) An another approach is to just create a new RecordType directly in the instance, move all the records from your packaged record type to that new 'local' record type, and then you can remove the package. – BritishBoyinDC Mar 4 '13 at 16:30
  • @BritishBoyinDC Calling Database.emptyRecycleBin(deletedProducts); immediately after deleting a list of products helps with the first issue. But you are right, as the number of records increases an uninstall script will run into limit issues. – Daniel Ballinger Mar 4 '13 at 18:59
2

SAFE HARBOR: best to double check if this works on a Sandbox, before executing this on your production data. I have just written this here without explicitly testing

What you will have to do is change your profile settings to include the --master-- record type in order to "see" it, you will also have to do this for every profile on your org, to make sure your Record Type isn't being used by other profiles, else you won't be able to delete the record type

  1. Go to Your Name -> Setup
  2. Administration Setup -> Manage Users -> Profiles
  3. Select your profile, and go to Record Type Settings
  4. Choose your SObject (Product2) -> Edit
  5. In order to include --Master--, you will have to remove the other Record Types
  6. Save
  7. Repeat for every profile in your org

Side note:

I don't think it is actually necessary to move records to another recordtype with code, try going to your SObject -> Record Types -> Select your record type -> Deactivate -> And now try deleting it, you should get the option to move all the records with that recordtype to another.

If you would need to do it with code, this is probably the easiest way.

Now you have multiple things you can do, but either way you must update all your SObjects (Product2) with that recordtype in your database and put the RecordTypeId on (blank), you can do this via the dataloader, by first exporting, then clearing all the values in RecordTypeId, and doing an update.

But I find the easiest way to achieve this is by Apex, more precisely executing Anonymous Apex via the Eclipse IDE

  1. Start Eclipse
  2. Add your project
  3. Next look for the View Execute Anonymous, it can be somewhere on your screen but if you can't find it go for: Window -> Show View -> Execute Anonymous

Execute Anonymous

  1. Make sure you select the correct Project when executing.
  2. Execute the following code:
List products = new List([SELECT Id, RecordTypeId FROM Product2 WHERE RecordTypeId != NULL]); 
for(Product2 p : products)
{
  p.RecordTypeId = NULL;
}
update products;

Now you'll need to deactivate your recordtype, and then delete it

| improve this answer | |
  • Thanks. I tried something very much like your code sample to set the Product2 RecordTypeIds to null and it didn't work for me. The RecordType values remained unchanged. I'll have another go when I'm back in the office to see if I missed something. – Daniel Ballinger Mar 1 '13 at 9:35
  • I just had to do this myself, I don't think you actually need to do any code executing, just remove the record type from the profiles, deactive it, and then delete. It just worked for me (one thing: I am not absolutely sure there was data with that record type, so you might still need to do the clearing) – pjcarly Mar 6 '13 at 15: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.