Question on updating data structures of stable variables in Motoko

Right, but the fact that we use Candid to serialize Motoko stable variables is undocumented, and an implementation detail we would like to be free to change. Rely on it at your peril.

I implemented the method for adding the new field to the stable variable that both you and @jzxchiang suggested. When I did, everything deployed correctly without any errors rendering in the console. but when i go to check the changes in the browser, The canister traps with this error:

index.js:2 Uncaught (in promise) Error: Call was rejected:
  Request ID: c021af817518bdc3e1c2db55c75df522d34e6b6b6b686eb2634ea805a706e4e3
  Reject code: 5
  Reject text: Canister ... trapped explicitly: IDL error: did not find field read in record

    at mt (index.js:2:117316)
    at async St.r (index.js:2:121300)
    at async index.js:2:648391

I’ve tried putting the logic in both the postupgrade hook and the preugrade hook to see if either of them would work and both yield this same console error in the browser. Locally, I was able to resolve this issue by deleting the .dfx file and then deploying again, but that strategy doesn’t work for resolving this error on the IC. Any ideas? @claudio @AdamS , I’d love y’all’s input too if you y’all have an idea for a solution.

1 Like

Are you using the latest dfx? In 0.9.3, dfx will certainly issue a warning when you add an optional field.

Similarly for the frontend, there was a bug in earlier versions of agent-js that prevents you from deserializing an opt field when it’s missing on the wire.

I was using version 0.9.2. I just upgraded it and tried again, but still no luck with the added optional field. I’ll retry migrating the data again using the upgrade hooks and see what that yields.

Any update on better ways of doing this or is copying the data in postupgrade onto the new var still the way to go?

Still the way to go, I’m afraid.

2 Likes