When deploying one of my existing canisters I get following warning for MOST of my stable variables:
(unknown location): Compatibility error [M0169], stable variable data_transactions of previous type
var [Transaction]
cannot be discarded; promote to type Any instead
Do you want to proceed? yes/No
If I proceed will my stable variables be deleted? Thing that’s weird is that I only removed 2 and added another 2, I added another function and modified some other functions.
Thanks!
EDIT:
I’ve compared .most and .old.most files and it appears I’m getting this warning for all stable variables that in .most file are listed below one that I added.
Example, I modified config_royatly. Those that are above - so config_owner, config_marketplace, etc. are fine and don’t give warning. But data_assetCanistersTableState and those below do.
stable var config_initial_sale_royalty_address : Text;
stable var config_marketplace_open : Int;
stable var config_owner : Principal;
stable var config_royalty : [(AccountIdentifier__2, Nat64)];
stable var data_assetCanistersTableState : [(Principal, Nat)];
stable var data_assetsTableState : [(AssetHandle, Asset__1)];
stable var data_capEventsQueueState : [CapIndefiniteEvent];
stable var data_chunksTableState : [(ChunkId, Blob)];
stable var data_disbursementQueueState :
Am I safe to continue or will this delete all my data stored in these stable variables?
You aren’t really supposed to remove (discard) variables altogether, just promote them to type Any if you want to drop their storage costs.
The issue, IIRC, is that removing the variable would allow you to re-introduce and define it at a different type in a later upgrade, and if you used that new code to directly upgrade from a version with the old typing, you might wind up unintentionally losing data.
I don’t think this issues is discussed here, but you may still find the rest of the discussion useful:
If you’ve changed the types of some variables in incompatible ways (ie, not supertype of the old type),
then you may indeed lose data, because the upgraded canister will run the new initializer for those expressions on failure to decode the previous value at the new, but incompatible, expected type.
It’s benign, in the sense that the error reporting is wrong after the first violation is reported, but the end result - that stable-compatibility does not hold - is still valid.
Thanks alot for reporting it and for sending me a repro!