Regarding package upgrades

Hello!

I need advice regarding an upgrade.

When attempting to upgrade Package B, which depends on Package A, I encountered a dependency error.

The publish history for Package A and Package B is as follows (addresses are examples):

  1. Package A published (Version 1)
    → PackageID: 0xa1
    → UpgradeCap: 0xa2
  2. Published Package B with a dependency on Package A (Version 1)
    → PackageID: 0xb1
    → UpgradeCap: 0xb2
  3. Upgraded Package A (to Version 2)
    → PackageID: 0xa3
  4. Attempted to upgrade Package B with a dependency on Package A (to Version 2)
    → Dependency error

Settings and error message during upgrade failure (1)
Package A’s Move.toml

[package]
published-at = “0xa3”

[addresses]
A = “0xa3”

Package B’s Move.toml

[package]
published-at = “0xb1”

[dependencies]
A = { local = “../a”, override = true }

[addresses]
A = “0xa3”

During Upgrade Execution

% sui client upgrade --verify-deps --dry-run --upgrade-capability 0xb2
Failed to publish the Move module(s), reason: [warning] Multiple source verification errors found:

- On-chain version of dependency BraveConfig::config was not found.
- Local version of dependency 0xb1::config was not found.

This may indicate that the on-chain version(s) of your package's dependencies may behave differently than the source version(s) your package was built against.

Fix this by rebuilding your packages with source versions matching on-chain versions of dependencies, or ignore this warning by re-running with the --skip-dependency-verification flag.

Configuration and Error Messages for Upgrade Failures (2)
A Package’s Move.toml

[package]
published-at = “0xa1”

[addresses]
A = “0xa1”

B Package’s Move.toml

[package]
published-at = “0xb1”

[dependencies]
A = { local = “../a”, override = true }

[addresses]
A = “0xa1”

During upgrade execution

% sui client upgrade --verify-deps --dry-run --upgrade-capability 0xb2
Failed to publish the Move module(s), reason: [warning] Local dependency did not match its on-chain version at 0xb1::BraveConfig::config

This may indicate that the on-chain version(s) of your package's dependencies may behave differently than the source version(s) your package was built against.

Fix this by rebuilding your packages with source versions matching on-chain versions of dependencies, or ignore this warning by re-running with the --skip-dependency-verification flag.

I’m stuck because linking the package to either the pre-upgrade or post-upgrade address results in an error.
Please point out any mistakes if you find them.

The issue you are facing is rooted in how the Sui Move VM handles package identity and the linkage of upgraded dependencies.
:books: Official Sui Documentation
The core concept is explained in the Sui Move documentation regarding package identity and upgrades.

  • Upgrading Packages - Sui Documentation
  • Automated Address Management: (This section explains the concept of using the ORIGINAL-ADDRESS.)
    :memo: What Caused the Issues and What to Do
    The fundamental rule on Sui is:

All packages must always reference their dependencies by the dependency’s original package ID, regardless of how many times the dependency has been upgraded.

The Sui framework uses an internal linkage table to map the Original ID (used in the bytecode, e.g., 0xa1) to the Latest Object ID (the actual location of the latest code, e.g., 0xa3).
:cross_mark: Issue 1: Linking to the New ID (0xa3)

Package A New ID: 0xa3 Package B Original ID: 0xb1
[addresses] A = “0xa3” [addresses] A = “0xa3” (Mistake)
Cause:
You updated Package B’s Move.toml to reference Package A at its new ID (0xa3). The upgrade transaction for Package B (at 0xb1) must preserve the dependency structure defined when it was originally published. The original Package B (0xb1) depended on Package A at 0xa1. The Sui verifier rejects the upgrade because the dependency path in the new bytecode (pointing to 0xa3) does not match the on-chain package’s original dependency path (pointing to 0xa1).
:cross_mark: Issue 2: Using --verify-deps
Package A Original ID: 0xa1 Package B Original ID: 0xb1
[addresses] A = “0xa1” (Correct Address) [addresses] A = “0xa1” (Correct Address)
Cause:
When you compile Package B (Version 2), the compiler uses the local source for Package A (Version 2). The --verify-deps flag then performs a strict check:
  • It resolves the dependency name A to the address 0xa1.
  • It compares the local source code of Package A (Version 2) against the on-chain source code associated with the original address 0xa1 (which is Package A Version 1).
    Since Package A was upgraded, its source code has changed, causing the verification check to correctly fail due to a source code mismatch between Version 1 and Version 2.
    :white_check_mark: Solution: Correct Configuration and Command
    You need to combine the correct dependency address from Failure (2) with the explicit instruction to skip dependency verification.
  1. Correct Move.toml Configuration
    Ensure your local packages are configured as follows:
    | File | Field | Value | Reason |
    |—|—|—|—|
    | Package B/Move.toml | [package] published-at | 0xb1 | Must be B’s Original Package ID. |
    | Package B/Move.toml | [addresses] A | 0xa1 | Must be A’s Original Package ID. |
    | Package B/Move.toml | [dependencies] A | { local = “../a”, override = true } | Links to the latest local source code of A (Version 2). |
  2. Correct Upgrade Command
    Since you have already successfully upgraded Package A, you are asserting that the new version of Package B works with the upgraded Package A (0xa3). You must skip the redundant and failing source verification check.

# Use --skip-dependency-verification

sui client upgrade --dry-run --skip-dependency-verification --upgrade-capability 0xb2

# If the dry run succeeds, proceed with the actual upgrade:

sui client upgrade --skip-dependency-verification --upgrade-capability 0xb2
2 Likes