I've just upgraded some subscriber orgs to a new version of our managed package. Now, we're seeing some erroneous behaviour in the subscriber org where the only explanation I can see is that sometimes, it's still running the old version of the package.

I know that they have Process Builder flows, and custom Apex that ultimately lead to running triggers in the package.

And I can see that the Apex is built against an old version of the package.

So, question 1: How does SF resolve which version of the package to use?

For example, consider the following scenario:

The subscriber has a trigger, SubscriberTrigger1, built against v1.0 that ends up calling a managed trigger, ManagedTrigger1. SubscriberTrigger1 also ends up calling another subscriber trigger SubscriberTrigger2 which is built against v1.1 of the package. SubscriberTrigger2 ends up calling ManagedTrigger2.

Does SF keep checking the current context of which version of the package to run so that when you run it, you the following sequence:

SubscriberTrigger1, ManagedTrigger1[v1.0], SubscriberTrigger2, ManagedTrigger2[v1.1]

So, this would mean that when I write v1.1, I need to account for the possibility that v1.0 could still be running as well? Fine for when I'm adding, or optimising functionality. Nightmare, if I'm changing what I write to the database e.g. ManagedTrigger2[v1.1] expects a value to have been written to the database by ManagedTrigger1[v1.1], but that value is missing because the subscriber has ended up making ManagedTrigger1[v1.0] run instead.

What about asynchronous code? Do future, batch, and queueable still come from the same version as was declared in subscriber's Apex?

What about dependency injection by doing Type.forname('MyClass').newInstance() in the package? Does this stick with the same version as the last piece of subscriber code?

Also, does this versioning also apply to Process Builder? I can't see any setting for PB that sets it against a specific package version.

Obviously, I've googled this but failed to find any documentation because the terms I'm searching for just seem to generic.


Usually, it is stored in metadata which version of a managed package is used, like a dependency. As far as I remember it is stored like this in metadata.xml for apex classes/triggers


This is also configurable in Salesforce Setup -> Develop -> Apex Classes -> Class -> Version Settings.

Basically, this is the version of your package the custom class/trigger would use for any calls.

From the metadata it looks like Process Builder always operates on the last version in the org. At least it doesn't store a version.

Also, here's a doc on Apex Class metadata: https://developer.salesforce.com/docs/atlas.en-us.api_meta.meta/api_meta/meta_classes.htm

Hope that helps.

| improve this answer | |
  • Thanks for the response, but that doesn't answer any of the questions I had. The question is, how do the version setting get applied at run-time? I probably should have mentioned it in the question, butI'd already looked at the metadata for PB, and could find no version number in there. – Aidan Aug 20 '18 at 11:52
  • @Aidan I took a look at the PB metadata, looks like you're right about it. I'll remove that part form the answer. As for the code, Salesforce determines what version to call based on the class/trigger metadata. So if your customer created a class based on version 1.0 and then you updated the package to 1.1, your customer's code will still use version 1.0 until they change the metadata for your their classes/triggers. I don't think you can do it for them using just your LMA or packaging interface – nchursin Aug 20 '18 at 12:01
  • It still seems like you haven't read the question, the question is how does it scope that when you move from one subscriber class to another? And how does that change as it is invoked from different subscriber classes? And how does that change in asynchronous code? And how about dependency injection. The base case is clear, the further ramifications are not. – Aidan Aug 20 '18 at 12:04
  • Ok, sorry, will make it more clear. As far as I know, the last class in a chain determines which version will be called. E.g. Trigger[1.2] calls Class [1.1] calls Class [1.0] - 1.0 will be used. Basically, the very caller determines the version of the callee. Here is one more link on versioning developer.salesforce.com/docs/atlas.en-us.apexcode.meta/… Please, notify me if you find any other information – nchursin Aug 20 '18 at 14:16
  • Thanks for your help. Still lots of unanswered questions, but maybe this is the best we can get. – Aidan Aug 21 '18 at 10:51

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.