While performing a development I replaced a class name (from ExampleCtrl to ExampleController) and a few methods were also renamed.

While this package was correctly installed on my scratch org, it is throwing an error while being deployed to UAT (and I am assuming it will throw the same one when installed on PROD), which is:

Apex compile failure, 
Details: Apex class ExampleCtrl: line 4, column 61: Method does not exist or incorrect signature: void getRecords(String) from the type ExampleService.

Note that ExampleCtrl was renamed, so I wouldn't expect it to be compiled. Additionally, the package is being installed with the --upgradeType flag set to DeprecateOnly. I could simply delete the ExampleCtrl class from UAT and then install the new version of the package, but this isn't a viable solution as it won't work in PROD environments.

Does anyone know the root cause and if there is a workaround in order to correctly deploy this metadata?

Best regards and thank you in advance!

1 Answer 1


As at Spring '21, 2GP managed packages do not support component deletion, as covered in the 1GP vs 2GP gap documentation. A rename is equivalent to delete (old name) and add (new name). Salesforce plan to add this ability in the future according to webinars and presentations around 2GP.

Your solution, therefore, is to add back in the ExampleCtrl class to your source base for your 2GP. You can probably have it empty, but if any of its methods were global you will need them in the class too (with empty bodies).

You probably need to adjust your ancestry tree/path to leave this broken version of your 2GP as a dead-end branch.


  1. There's a pilot for 2GP managed package metadata deletion.
  2. Unlocked packages already support metadata deletion.

If your package is an unlocked package, this could still be one of those types of problem you can see with 1GP, where Salesforce's dependency analysis fails to correctly evaluate during installation. The sort of failure scenario we've seen here is where you remove dependencies on a class or method (i.e. usages of that class or method) in the same version as you delete the class or method itself. The solution here is similar to what I mentioned above; create a package version with dependencies removed and an empty version of the method, or a cut down version of the class with empty methods, then create a second version that actually removes the class or method. It is then necessary to install both versions in sequence on a given org when upgrading.

  • 2gp does kind of support deletion, but you have to ask for it. --upgradetype Delete Still, +1 from me.
    – sfdcfox
    Apr 20, 2021 at 14:53
  • @sfdcfox I believe that's more for when you install a 1GP upgrade since these allow deletion of components (once enabled by Salesforce on the packaging org). Right?
    – Phil W
    Apr 20, 2021 at 15:15
  • Not from what I've seen in the docs. This is definitely suppose to be a 2gp feature. One of its main "selling points", even. I only have limited experience with it, though, but going 2021 is the year that changes.
    – sfdcfox
    Apr 20, 2021 at 15:19
  • @sfdcfox having looked into this, I believe this feature is intended for 2gp unlocked packages. Take a look at this documentation that discusses this option and this documentation that shows 2gp managed package metadata deletion is only a pilot at this time.
    – Phil W
    Apr 22, 2021 at 7:25

You must log in to answer this question.

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