I ran into this error last week. First of all, what I describe below may not be the only cause of this error. With that in mind, please read on…
I ran into “heap out of bounds” when trying to upgrade a motoko canister. It turned out that the error was caused by incompatible types of my stable variable. I think the next release of dfx will have better error messages that actually prevent you from doing the upgrade when such an incompatibility is detected, instead of allowing your upgrade request to be sent and then got a runtime error back. I might have jumped the gun, this may not be ready yet…
In any case, it should be easy to understand that why one can’t automatically upgrade
stable var i : Int = ...
to stable var j : Nat = ...
. In other words, old value of a stable variable may not satisfy its new type. So there is an entire set of subtype rules to help check this.
It is however not an easy task to check manually when your type is more complex. For example, one is allowed to add a new field to a record as long as the new field has an option type. This is okay, but I was adding a mutable field var name = ....
, then this is not okay! I ran into “heap out of bound” error due to this. Eventually I resolved this problem by doing a conversion between old and new type in the postupgrade()
function.
It is actually better to run into errors during upgrade. It is much worse when the upgrade went through and yet data is lost in stable variables! It can also happen! This is why I think it is crucial to have automatic checks on type compatibility of stable variables before attempting an upgrade.
Hope it helps!