dfx 0.28.0 container upgrade fails: no data loss. Use an explicit migration function
Dear ICP support team!
After upgrading dfx from version 0.25.0 to 0.28.0, the following message appears during container upgrade, preventing the upgrade.
dfx canister install delta -m upgrade --ic
Please enter the passphrase for your identity: [hidden]
Decryption complete.
WARNING!
Candid interface compatibility check failed for canister 'delta'.
You are making a BREAKING change. Other canisters or frontend clients relying on your canister may stop working.
Method createVerification is only in the expected type
Do you want to proceed? yes/No
yes
Error: Failed to install wasm module to canister 'delta'.
Caused by: Stable interface compatibility check issued an ERROR for canister 'delta'.
Upgrade will either FAIL or LOSE some stable variable data.
(unknown location): Compatibility error [M0170], stable variable CanisterMap of previous type
{
DTCTArchives : SBuffer<CreditsActorData>;
var ICPfundsActor : [ICPfundsActor__1];
LedgerArchives : TrieMap<Text, [CanisterId]>;
Ledgers : TrieMap<CoinCode, CanisterId>;
USCTArchives : SBuffer<CreditsActorData>;
accountCanisters : SBuffer<AccountActorData>;
adminPrincipal : Principal;
var dappCenterCanisterId : CanisterId;
var dappCenterSqlCanister : CanisterId;
ic : ICActor;
var index : Index;
var mcWalletActor : [MCWalletActor__1];
var mobileActor : [MobileActor__2];
var pendingUSCTActor : [Actor__2];
var roadMapCanisterId : CanisterId;
var statsActor : [StatsActor__1];
totalCredit : TotalCredit__1
}
cannot be consumed at new type
{
DTCTArchives : SBuffer__857143345<CreditsActorData__322513469>;
var ICPfundsActor : [ICPfundsActor__29272369];
LedgerArchives : TrieMap__791300389<Text, [CanisterId__923181316]>;
Ledgers : TrieMap__791300389<CoinCode__166952260, CanisterId__923181316>;
USCTArchives : SBuffer__857143345<CreditsActorData__322513469>;
accountCanisters : SBuffer__857143345<AccountActorData__351512712>;
adminPrincipal : Principal;
var dappCenterCanisterId : CanisterId__923181316;
var dappCenterSqlCanister : CanisterId__923181316;
ic : ICActor__550475663;
var index : Index__679396598;
var mcWalletActor : [MCWalletActor__114623647];
var mobileActor : [MobileActor__944888];
var pendingUSCTActor : [Actor__1053442990];
var roadMapCanisterId : CanisterId__923181316;
var statsActor : [StatsActor__800506637];
totalCredit : TotalCredit__342463311
} without data loss. Use an explicit migration function.
First, we haven’t made any changes to the CanisterMap declaration type. We believe this error message may be due to the CanisterMap structure being too complex, preventing the ICP system from correctly detecting its consistency.
We encountered similar errors during previous dfx container upgrades, but after inquiring, the upgrade completed successfully.
The CanisterMap declaration is as follows:
public type CanisterMap = {
var index : T.Index; //
totalCredit : TotalCredit;
accountCanisters : T.SBuffer<AccountActorData>;
adminPrincipal : Principal;
ic : IC.ICActor;
var mobileActor : [MobileActor];
DTCTArchives : T.SBuffer<CreditsActorData>;
USCTArchives : T.SBuffer<CreditsActorData>;
Ledgers : STrieMap.TrieMap<T.CoinCode, T.CanisterId>;
LedgerArchives : STrieMap.TrieMap<Text, [T.CanisterId]>;
var statsActor : [StatsActor];
var pendingUSCTActor : [PendingUSCT.Actor];
var ICPfundsActor : [ICPfundsActor];
var mcWalletActor : [MCWalletActor];
var dappCenterCanisterId : T.CanisterId;
var dappCenterSqlCanister : T.CanisterId;
var roadMapCanisterId : T.CanisterId;
};
Did you change any of the other types involved in this, e.g. by removing a field from an object or acto or promoting to type Any? There’s quite a few actor types in there. Have any changed?
Is the code public, or could share the .most files for the pre and post-upgrade canister? You can DM them to me if sensitive.
The CanisterMap declaration type remained unchanged. I temporarily downgraded DFX to 0.25.0, and the container upgrade was successful.
Therefore, it should be a problem of dfx version difference.
When I sent a file attachment, the forum system seems to not be able to upload non-image attachments, even in private messages. Could you please provide your email address?
Under @Paul’s prompt, after successfully upgrading through 0.25.0, we upgraded 0.25.0 to 0.28.0 yesterday, and the container generation was successful.
But today we still refuse to upgrade the container code again (this is the case when the online version and compiled version are 0.28.0 at the same time).
Of course, our Motoko code structure does not make any changes, but just modify the code inside a function.
The prompts are as follows:
dfx canister install delta -m upgrade --ic
Please enter the passphrase for your identity: [hidden]
Decryption complete.
Error: Failed to install wasm module to canister 'delta'.
Caused by: Stable interface compatibility check issued an ERROR for canister 'delta'.
Upgrade will either FAIL or LOSE some stable variable data.
(unknown location): Compatibility error [M0170], stable variable CanisterMap of previous type
{
DTCTArchives : SBuffer__857143345<CreditsActorData__322513469>;
var ICPfundsActor : [ICPfundsActor__29272369];
LedgerArchives : TrieMap__791300389<Text, [CanisterId__923181316]>;
Ledgers : TrieMap__791300389<CoinCode__166952260, CanisterId__923181316>;
USCTArchives : SBuffer__857143345<CreditsActorData__322513469>;
accountCanisters : SBuffer__857143345<AccountActorData__351512712>;
adminPrincipal : Principal;
var dappCenterCanisterId : CanisterId__923181316;
var dappCenterSqlCanister : CanisterId__923181316;
ic : ICActor__550475663;
var index : Index__679396598;
var mcWalletActor : [MCWalletActor__114623647];
var mobileActor : [MobileActor__944888];
var pendingUSCTActor : [Actor__1053442990];
var roadMapCanisterId : CanisterId__923181316;
var statsActor : [StatsActor__800506637];
totalCredit : TotalCredit__342463311
}
cannot be consumed at new type
{
DTCTArchives : SBuffer__857143345<CreditsActorData__322513469>;
var ICPfundsActor : [ICPfundsActor__29272369];
LedgerArchives : TrieMap__791300389<Text, [CanisterId__923181316]>;
Ledgers : TrieMap__791300389<CoinCode__166952260, CanisterId__923181316>;
USCTArchives : SBuffer__857143345<CreditsActorData__322513469>;
accountCanisters : SBuffer__857143345<AccountActorData__351512712>;
adminPrincipal : Principal;
var dappCenterCanisterId : CanisterId__923181316;
var dappCenterSqlCanister : CanisterId__923181316;
ic : ICActor__550475663;
var index : Index__679396598;
var mcWalletActor : [MCWalletActor__114623647];
var mobileActor : [MobileActor__944888];
var pendingUSCTActor : [Actor__1053442990];
var roadMapCanisterId : CanisterId__923181316;
var statsActor : [StatsActor__800506637];
totalCredit : TotalCredit__342463311
} without data loss. Use an explicit migration function.
dfx --version
dfx 0.28.0
At the same time, I have shared the new .most file to your private message, thank you very much!
I’ve taken a look a the .most files and in both cases, (at least) one of the actor types in the new version contains a field (method) that is not provided in the old version. I’m not sure how these differences are arising, but I don’t think it’s a moc bug.
Also, even before we tightened the rules regarding stable compatibility, adding a field to on object was not allowed. Older versions of dfx would (dangerously) allow you to ignore the stable compatibility warning, so perhaps that is what allowed the upgrade to work.
In the particular case of adding a field to an actor, this not dangerous, since both the original and extended version have the same representation in memory (a principal), but that would no be safe for ordinary objects, which would now be missing a field that is assumed to be there.
The object reported in the error comes from CanisterMap, which has a relatively deep structure.
However, we haven’t added any new fields to the existing object.
We’ve discovered that this is related to the command environment for the command “dfx canister install xxx -m upgrade --ic …” Currently, only DFX version 0.26.1 (or earlier) can be used to upgrade our container.
However, we can still compile using version 0.28.0, then upgrade to version 0.26.1 and execute “dfx canister install xxx -m upgrade.”
We hope you can resolve this issue in a new version. Thank you!