How to upgrade the canister and maintain state when modify the fields of the data structure?

I’m about to upgrade a Motoko canister, and changed the type of a state variable’s field from Nat to ?Nat. and I implemented preupgrade and postupgrade.

But when upgraded, I got the error:

Upgrading code for canister market, with canister_id xxxxxxxx
Error: The Replica returned an error: code 5, message: "Canister xxxxxxxx trapped explicitly: buffer_size: unexpected variant"

I speculate that when executing postupgrade, ic saved the original Nat to the current ?Nat, so the buffer_size error appeared.

Is the upgrade process like this?

  1. Execute preupgrade of previous version code;
  2. Install the new version code;
  3. Execute postupgrade of new version code

That is the upgrade process yes.

You could temporarily add code to the postupgrade method that migrates/converts buffer_size from Nat to ?Nat and deploy once with this. Then remove this migration code before the next deploy.

1 Like

I feel like I misunderstood the bug before. After changing the data structure, it has been successfully upgraded once, but the second upgraded has failed. even there is nothing changed between first upgraded and second upgraded.

The error message is generated here, does anyone know what this code means?