
Andrew Hanna

Andrew Hanna

Short answer: cross-package dependency resolution is how Salesforce
decides which packages must already be present, and at which versions, before another
package can install or upgrade. You declare it in the dependencies array
of sfdx-project.json, listed in installation order. Get the order and
version floors right and subscriber upgrades are boring; get them wrong and an org
lands on a version it cannot move off.
A dependency exists when metadata in one package references metadata in another: a Flow on a managed object, an Apex class extending a base class, a field set on someone else's field. The practical consequence is a precondition: the referenced package must be installed first, at a version at least as new as the one you built against, or the install fails.
In the package directory entry of sfdx-project.json, in either of two
forms:
{ "package": "[email protected]" }
{ "package": "MyPackage", "versionNumber": "1.0.0.RELEASED" }
Three rules matter more than the syntax.
"calculateTransitiveDependencies": true and you declare only direct
dependencies while the indirect ones are computed for you. Leave it off and you list
every level yourself, forever.
This constrains the architecture, so check it before you draw it.
A 1GP base package under a 2GP extension is the most common dependency design that has to be undone late, and it is expensive by then. Read the supported combinations before the first build, not after.
RELEASED follows your latest released version, which
is convenient in development and a surprise in a release build.
SubscriberPackageVersion tells you what is installed in that org and at
which version, which beats reading the Installed Packages page and hoping.
If you cannot state that order from memory, neither can your support team when a customer is blocked.
The sequence that works when a base package changes: release the base version, move subscribers onto it with a recommended version or a push upgrade, then release the dependent package that requires it. Reversing those two produces an upgrade that fails a precondition in an org you cannot see and cannot fix from your side.
sfdx-project.json on every pipeline run and fail
the build on a cycle.
Serpent does cross-package dependency resolution, 1GP, 2GP and managed-package workflows and version management across subscriber orgs on every plan, including the free one. More playbooks live in our SF Guides library.
Can a managed 2GP package depend on a managed 1GP package?
Not by default. Salesforce blocks the combination, and an individual override is requested through a case with Salesforce Partner Support.
Do I have to list transitive dependencies?
Only if you want to. Setting "calculateTransitiveDependencies": true lets
you declare direct dependencies while the indirect ones are calculated. Without it,
every level has to be listed by hand.
What happens if two packages depend on each other?
Nothing good, because circular dependencies are not supported. Extract the shared metadata into a lower package that both depend on.
Which package do I upgrade first in a subscriber org?
The one furthest down the graph. Dependencies are upgraded before the packages that require them, in the same order they were installed.
Why does my customer's upgrade fail with a dependency error?
Usually a version floor. The installed base package is older than the version your new release requires, so upgrade the base package first and retry.
Commitment free!