How to safely delete stable storage

I had a had a stable structure stable var proposals : Trie.Trie<Nat, Types.Proposal> = Trie.empty(); that I deprecated. When trying to remove it from the canister and deploy, i get the following error:

Stable interface compatibility check failed for canister 'dao'.
Upgrade will either FAIL or LOSE some stable variable data.

(unknown location): Compatibility error [M0169], stable variable proposals of previous type
  var {#branch : Branch<Nat, Proposal>; #empty; #leaf : Leaf<Nat, Proposal>}
cannot be discarded; promote to type `Any` instead
(unknown location): Compatibility error [M0169], stable variable proposalsV2 of previous type
  var
   {#branch : Branch<Nat, ProposalV2>; #empty; #leaf : Leaf<Nat, ProposalV2>}
cannot be discarded; promote to type `Any` instead
(unknown location): Compatibility error [M0169], stable variable votingHistories of previous type
  var
   {
     #branch : Branch<Principal, List<{id : Nat; option : Nat}>>;
     #empty;
     #leaf : Leaf<Principal, List<{id : Nat; option : Nat}>>
   }
cannot be discarded; promote to type `Any` instead

Do you want to proceed? yes/No

How can I safely remove the proposals stable variable?

@claudio @rossberg

2 Likes

I think you may be able to just proceed, but I’d appreciate a clarification as well.

What I’m confused about is that it throws compatibility errors for the stable variables I didn’t even touch :thinking:

maybe @chenyan knows something?

As long as the preupgrade hook in current (before this deploy) canister doesn’t mention proposals, it is safe to remove them. Or safer, you can mark proposals as Any type. The warning says you may lose stable variable data, because you deleted proposals, which is not always unsafe.

To double check, you can look at .dfx/local/canisters/dao (or .dfx/ic/canisters/dao if deployed to IC) directory, there should be a .old.most and .most file. You can then compare the stable signature before and after this upgrade to see if you may lose any data.

What do I need to look for?

The stable var proposals isn’t used anywhere anymore, it’s declaration is the only thing that’s left in the code. So I can safely delete it now? Does setting the type to Any free memory as well? Why do I even have to do that? What’s the impact of setting the type to Any

If you don’t use proposals, it’s safe to delete it. Setting to Any also frees the memory: it decodes the old data from stable memory and discard it.

1 Like