I try to migrate a new non optional field in my heap memory using Serde but, I get following error:
Request ID: 2e0dc0659e5c1c445882d82deadd0df89c18a0f074b24b5b5d533852aa011fea
Reject code: 5
Reject text: Canister xo2hm-lqaaa-aaaal-ab3oa-cai trapped explicitly: Panicked at 'called `Result::unwrap()` on an `Err` value: "Custom(Fail to decode argument 0\n\nCaused by:\n Subtyping error: field memory is not optional field)"', src/satellite/src/lib.rs:104:50
at m_ (file:///opt/homebrew/lib/node_modules/@junobuild/cli/dist/index.js:42:2120)
I try to upgrade existing canister without reinstalling those - preserving the state.
I can set the memory as Option<Memory> but, because itâs a really important information, I was hoping to be able to introduce it as a non optional value. Just feel wrong to have it optional but, indeed if no other option, I ultimately have to, agree with you.
If you want to preserve the state then yeah youâd have to introduce optional types.
Or what weâre doing is ensuring that every single type has a valid default (even if itâs something like Unspecified which wonât pass a validation check.)
That way you can change the schema, and when you deserialize into the type it
a) skips values that exist in the serialized data that donât exist in the new type
b) sets a default for values that donât exist in the data but are new to the type.
As long as your types have Serialize/Deserialize and Default this should work. We havenât really tested it a lot though.
I had to fix some stuffs in a FE project so, when I finally went back to mine I decided to accept my fate and set those new variable as Option<Memory>.
Upgrade worked like a charm and now there is the first Junoâs smart contract on mainnet that supports stable memory.