# Compatibility error

**URL:** <https://forum.dfinity.org/t/compatibility-error/20275>\
**Category:** Developers\
**Created:** [May 26, 2023, 10:56pm UTC](https://forum.dfinity.org/t/compatibility-error/20275 "2023-05-26T22:56:34Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![cryptoschindler](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/cryptoschindler/32/26_2.png) [@cryptoschindler](https://forum.dfinity.org/u/cryptoschindler)\
**Post date:** [May 26, 2023, 10:56pm UTC](https://forum.dfinity.org/t/compatibility-error/20275/1 "2023-05-26T22:56:34Z")

</div>

I get the following error:

```auto
(unknown location): Compatibility error [M0170], stable variable _stableChunks of previous type
  var [var StableChunk__6]
cannot be consumed at new type
  var [var StableChunk __6__ 1]

Do you want to proceed? yes/No

```

`StableChunk __6__ 1` does neither exist in `old.most` nor in `most`, why is this error thrown @claudio ?

`production.old.most`:

```auto
// Version: 1.0.0
type AccountIdentifier = Text;
type AccountIdentifier__1 = AccountIdentifier;
type AccountIdentifier __2 = AccountIdentifier__ 1;
type AccountIdentifier __4 = AccountIdentifier__ 1;
type AccountIdentifier __6 = AccountIdentifier__ 1;
type AccountIdentifier __8 = AccountIdentifier__ 1;
type Asset =
  {metadata : ?File; name : Text; payload : File; thumbnail : ?File};
type Balance = Nat;
type Balance__1 = Balance;
type DayCanisterCyclesData = [var Nat64];
type DayCanisterHeapMemorySizeData = [var Nat64];
type DayCanisterMemorySizeData = [var Nat64];
type DayData =
  {
    canisterCyclesData : DayCanisterCyclesData;
    canisterHeapMemorySizeData : DayCanisterHeapMemorySizeData;
    canisterMemorySizeData : DayCanisterMemorySizeData;
    updateCallsData : DayUpdateCallsCountData
  };
type DayDataId = Nat32;
type DayUpdateCallsCountData = [var Nat64];
type Disbursement =
  {
    amount : Nat64;
    fromSubaccount : SubAccount__4;
    to : AccountIdentifier__4;
    tokenIndex : TokenIndex__2
  };
type File = {ctype : Text; data : [Blob]};
type Frontend = {accountIdentifier : AccountIdentifier__8; fee : Nat64};
type Listing__1 =
  {
    buyerFrontend : ?Text;
    locked : ?Time__3;
    price : Nat64;
    seller : Principal;
    sellerFrontend : ?Text
  };
type Metadata =
  {
    #fungible :
      {decimals : Nat8; metadata : ?Blob; name : Text; symbol : Text};
    #nonfungible : {metadata : ?Blob}
  };
type Metadata__1 = Metadata;
type Sale =
  {
    buyer : AccountIdentifier__6;
    expires : Time__2;
    price : Nat64;
    slot : ?WhitelistSlot__1;
    subaccount : SubAccount__6;
    tokens : [TokenIndex__4]
  };
type SaleTransaction =
  {
    buyer : AccountIdentifier__6;
    price : Nat64;
    seller : Principal;
    time : Time__2;
    tokens : [TokenIndex__4]
  };
type Settlement =
  {
    buyer : AccountIdentifier__8;
    buyerFrontend : ?Text;
    price : Nat64;
    seller : Principal;
    sellerFrontend : ?Text;
    subaccount : SubAccount__8
  };
type StableChunk =
  ?{
     #legacy : StableState;
     #v1 :
       {
         nextTokenId : TokenIndex__1;
         owners : [(AccountIdentifier__2, [TokenIndex__1])];
         registry : [(TokenIndex __1, AccountIdentifier__ 2)];
         supply : Balance__1;
         tokenMetadata : [(TokenIndex __1, Metadata__ 1)]
       }
   };
type StableChunk__1 =
  ?{
     #legacy : StableState__1;
     #v1 : {assetsChunk : [Asset]; assetsCount : Nat};
     #v1_chunk : {assetsChunk : [Asset]}
   };
type StableChunk__2 =
  ?{#legacy : StableState__2; #v1 : {disbursements : [Disbursement]}};
type StableChunk __3 = ?{#legacy : StableState__ 3; #v1 : {isShuffled : Bool}};
type StableChunk__4 =
  ?{
     #legacy : StableState__4;
     #v1 :
       {
         failedSales : [(AccountIdentifier __6, SubAccount__ 6)];
         nextSubAccount : Nat;
         saleTransactionChunk : [SaleTransaction];
         saleTransactionCount : Nat;
         salesSettlements : [(AccountIdentifier__6, Sale)];
         sold : Nat;
         soldIcp : Nat64;
         tokensForSale : [TokenIndex__4];
         totalToSell : Nat;
         whitelist : [(Nat64, AccountIdentifier __6, WhitelistSlot__ 1)]
       };
     #v1_chunk : {saleTransactionChunk : [SaleTransaction]}
   };
type StableChunk__5 =
  ?{
     #legacy : StableState__5;
     #v1 :
       {
         frontends : [(Text, Frontend)];
         tokenListing : [(TokenIndex __5, Listing__ 1)];
         tokenSettlement : [(TokenIndex__5, Settlement)];
         transactionChunk : [Transaction__2];
         transactionCount : Nat
       };
     #v1_chunk : {transactionChunk : [Transaction__2]}
   };
type StableChunk__6 =
  {
    #v1 :
      {
        assets : StableChunk__1;
        disburser : StableChunk__2;
        marketplace : StableChunk__5;
        sale : StableChunk__4;
        shuffle : StableChunk__3;
        tokens : StableChunk
      }
  };
type StableState =
  {
    _nextTokenIdState : TokenIndex__1;
    _ownersState : [(AccountIdentifier__2, [TokenIndex__1])];
    _registryState : [(TokenIndex __1, AccountIdentifier__ 2)];
    _supplyState : Balance__1;
    _tokenMetadataState : [(TokenIndex __1, Metadata__ 1)]
  };
type StableState__1 = {_assetsState : [Asset]};
type StableState__2 = {_disbursementsState : [Disbursement]};
type StableState__3 = {_isShuffledState : Bool};
type StableState__4 =
  {
    _failedSalesState : [(AccountIdentifier __6, SubAccount__ 6)];
    _nextSubAccountState : Nat;
    _saleTransactionsState : [SaleTransaction];
    _salesSettlementsState : [(AccountIdentifier__6, Sale)];
    _soldIcpState : Nat64;
    _soldState : Nat;
    _tokensForSaleState : [TokenIndex__4];
    _totalToSellState : Nat;
    _whitelistStable : [(Nat64, AccountIdentifier __6, WhitelistSlot__ 1)]
  };
type StableState__5 =
  {
    _frontendsState : [(Text, Frontend)];
    _tokenListingState : [(TokenIndex __5, Listing__ 1)];
    _tokenSettlementState : [(TokenIndex__5, Settlement)];
    _transactionsState : [Transaction__2]
  };
type SubAccount = [Nat8];
type SubAccount__1 = SubAccount;
type SubAccount __4 = SubAccount__ 1;
type SubAccount __6 = SubAccount__ 1;
type SubAccount __8 = SubAccount__ 1;
type Time = Int;
type Time__2 = Time;
type Time__3 = Time;
type TokenIdentifier = Text;
type TokenIdentifier__1 = TokenIdentifier;
type TokenIdentifier __3 = TokenIdentifier__ 1;
type TokenIndex = Nat32;
type TokenIndex__1 = TokenIndex;
type TokenIndex__2 = TokenIndex;
type TokenIndex__4 = TokenIndex;
type TokenIndex__5 = TokenIndex;
type Transaction__2 =
  {
    buyer : AccountIdentifier__8;
    price : Nat64;
    seller : Principal;
    time : Time__3;
    token : TokenIdentifier__3
  };
type UpgradeDataDayTuple = (DayDataId, DayData);
type UpgradeData__1 = {#v1 : {dayData : [UpgradeDataDayTuple]}};
type UpgradeData __2 = UpgradeData__ 1;
type WhitelistSlot = {end : Time; start : Time};
type WhitelistSlot__1 = WhitelistSlot;
actor {
  stable var _assetsState : {_assetsState : [Asset]};
  stable var _canistergeekMonitorUD : ?UpgradeData__2;
  stable var _disburserState : {_disbursementsState : [Disbursement]};
  stable var _marketplaceState :
    {
      _frontendsState : [(Text, Frontend)];
      _tokenListingState : [(TokenIndex __5, Listing__ 1)];
      _tokenSettlementState : [(TokenIndex__5, Settlement)];
      _transactionsState : [Transaction__2]
    };
  stable var _revealTimerId : Nat;
  stable var _saleState :
    {
      _failedSalesState : [(AccountIdentifier __6, SubAccount__ 6)];
      _nextSubAccountState : Nat;
      _saleTransactionsState : [SaleTransaction];
      _salesSettlementsState : [(AccountIdentifier__6, Sale)];
      _soldIcpState : Nat64;
      _soldState : Nat;
      _tokensForSaleState : [TokenIndex__4];
      _totalToSellState : Nat;
      _whitelistStable : [(Nat64, AccountIdentifier __6, WhitelistSlot__ 1)]
    };
  stable var _shuffleState : {_isShuffledState : Bool};
  stable var _stableChunks : [var StableChunk__6];
  stable var _timerId : Nat;
  stable var _tokenState :
    {
      _nextTokenIdState : TokenIndex__1;
      _ownersState : [(AccountIdentifier__2, [TokenIndex__1])];
      _registryState : [(TokenIndex __1, AccountIdentifier__ 2)];
      _supplyState : Balance__1;
      _tokenMetadataState : [(TokenIndex __1, Metadata__ 1)]
    };
  stable var rootBucketId : ?Text
};

```

`production.most`

```auto
// Version: 1.0.0
type AccountIdentifier = Text;
type AccountIdentifier__1 = AccountIdentifier;
type AccountIdentifier __2 = AccountIdentifier__ 1;
type AccountIdentifier __4 = AccountIdentifier__ 1;
type AccountIdentifier __6 = AccountIdentifier__ 1;
type AccountIdentifier __8 = AccountIdentifier__ 1;
type Asset =
  {metadata : ?File; name : Text; payload : File; thumbnail : ?File};
type Balance = Nat;
type Balance__1 = Balance;
type DayCanisterCyclesData = [var Nat64];
type DayCanisterHeapMemorySizeData = [var Nat64];
type DayCanisterMemorySizeData = [var Nat64];
type DayData =
  {
    canisterCyclesData : DayCanisterCyclesData;
    canisterHeapMemorySizeData : DayCanisterHeapMemorySizeData;
    canisterMemorySizeData : DayCanisterMemorySizeData;
    updateCallsData : DayUpdateCallsCountData
  };
type DayDataId = Nat32;
type DayUpdateCallsCountData = [var Nat64];
type Disbursement =
  {
    amount : Nat64;
    fromSubaccount : SubAccount__4;
    to : AccountIdentifier__4;
    tokenIndex : TokenIndex__2
  };
type File = {ctype : Text; data : [Blob]};
type Frontend = {accountIdentifier : AccountIdentifier__8; fee : Nat64};
type Listing__1 =
  {
    buyerFrontend : ?Text;
    locked : ?Time__3;
    price : Nat64;
    seller : Principal;
    sellerFrontend : ?Text
  };
type Metadata =
  {
    #fungible :
      {decimals : Nat8; metadata : ?Blob; name : Text; symbol : Text};
    #nonfungible : {metadata : ?Blob}
  };
type Metadata__1 = Metadata;
type Sale =
  {
    buyer : AccountIdentifier__6;
    expires : Time__2;
    price : Nat64;
    slot : ?WhitelistSlot__1;
    subaccount : SubAccount__6;
    tokens : [TokenIndex__4]
  };
type SaleTransaction =
  {
    buyer : AccountIdentifier__6;
    price : Nat64;
    seller : Principal;
    time : Time__2;
    tokens : [TokenIndex__4]
  };
type Settlement =
  {
    buyer : AccountIdentifier__8;
    buyerFrontend : ?Text;
    price : Nat64;
    seller : Principal;
    sellerFrontend : ?Text;
    subaccount : SubAccount__8
  };
type StableChunk =
  ?{
     #v1 :
       {
         nextTokenId : TokenIndex__1;
         owners : [(AccountIdentifier__2, [TokenIndex__1])];
         registry : [(TokenIndex __1, AccountIdentifier__ 2)];
         supply : Balance__1;
         tokenMetadata : [(TokenIndex __1, Metadata__ 1)]
       }
   };
type StableChunk__1 =
  ?{
     #v1 : {assetsChunk : [Asset]; assetsCount : Nat};
     #v1_chunk : {assetsChunk : [Asset]}
   };
type StableChunk__2 = ?{#v1 : {disbursements : [Disbursement]}};
type StableChunk__3 = ?{#v1 : {isShuffled : Bool}};
type StableChunk__4 =
  ?{
     #v1 :
       {
         failedSales : [(AccountIdentifier __6, SubAccount__ 6)];
         nextSubAccount : Nat;
         saleTransactionChunk : [SaleTransaction];
         saleTransactionCount : Nat;
         salesSettlements : [(AccountIdentifier__6, Sale)];
         sold : Nat;
         soldIcp : Nat64;
         tokensForSale : [TokenIndex__4];
         totalToSell : Nat;
         whitelist : [(Nat64, AccountIdentifier __6, WhitelistSlot__ 1)]
       };
     #v1_chunk : {saleTransactionChunk : [SaleTransaction]}
   };
type StableChunk__5 =
  ?{
     #v1 :
       {
         frontends : [(Text, Frontend)];
         tokenListing : [(TokenIndex __5, Listing__ 1)];
         tokenSettlement : [(TokenIndex__5, Settlement)];
         transactionChunk : [Transaction__2];
         transactionCount : Nat
       };
     #v1_chunk : {transactionChunk : [Transaction__2]}
   };
type StableChunk__6 =
  {
    #v1 :
      {
        assets : StableChunk__1;
        disburser : StableChunk__2;
        marketplace : StableChunk__5;
        sale : StableChunk__4;
        shuffle : StableChunk__3;
        tokens : StableChunk
      }
  };
type SubAccount = [Nat8];
type SubAccount__1 = SubAccount;
type SubAccount __4 = SubAccount__ 1;
type SubAccount __6 = SubAccount__ 1;
type SubAccount __8 = SubAccount__ 1;
type Time = Int;
type Time__2 = Time;
type Time__3 = Time;
type TokenIdentifier = Text;
type TokenIdentifier__1 = TokenIdentifier;
type TokenIdentifier __3 = TokenIdentifier__ 1;
type TokenIndex = Nat32;
type TokenIndex__1 = TokenIndex;
type TokenIndex__2 = TokenIndex;
type TokenIndex__4 = TokenIndex;
type TokenIndex__5 = TokenIndex;
type Transaction__2 =
  {
    buyer : AccountIdentifier__8;
    price : Nat64;
    seller : Principal;
    time : Time__3;
    token : TokenIdentifier__3
  };
type UpgradeDataDayTuple = (DayDataId, DayData);
type UpgradeData__1 = {#v1 : {dayData : [UpgradeDataDayTuple]}};
type UpgradeData __2 = UpgradeData__ 1;
type WhitelistSlot = {end : Time; start : Time};
type WhitelistSlot__1 = WhitelistSlot;
actor {
  stable var _assetsState : Any;
  stable var _canistergeekMonitorUD : ?UpgradeData__2;
  stable var _disburserState : Any;
  stable var _marketplaceState : Any;
  stable var _revealTimerId : Nat;
  stable var _saleState : Any;
  stable var _shuffleState : Any;
  stable var _stableChunks : [var StableChunk__6];
  stable var _timerId : Nat;
  stable var _tokenState : Any;
  stable var rootBucketId : ?Text
};

```

---

<div class="post-metadata">

**Author:** ![claudio](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/claudio/32/322_2.png) [@claudio](https://forum.dfinity.org/u/claudio)\
**Post date:** [May 29, 2023, 10:47am UTC](https://forum.dfinity.org/t/compatibility-error/20275/2 "2023-05-29T10:47:05Z")

</div>

> [@cryptoschindler](#):
>
> ```auto
> var [var StableChunk__6]
> cannot be consumed at new type
> var [var StableChunk __6__ 1]
> 
> ```

My hunch is this is because the arrays are mutable so the type inside cannot be changed at all.  
Did any of the types reference from the mutable array element type change?

The type of a stable variable can only evolve to a supertype (so that the upgrade can consume the old value when initializing the field at the new type). Unfortunately, the subtyping relation between mutable arrays requires the element type to be equivalent, not just a subtype (as for immutable arrays). This is actually required for soundness, in general.

---

<div class="post-metadata">

**Author:** ![rossberg](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/rossberg/32/795_2.png) [@rossberg](https://forum.dfinity.org/u/rossberg)\
**Post date:** [May 29, 2023, 5:26pm UTC](https://forum.dfinity.org/t/compatibility-error/20275/3 "2023-05-29T17:26:48Z")

</div>

Didn’t the subtype check for stable upgrades ignore mutability? It shouldn’t matter there, right?

---

<div class="post-metadata">

**Author:** ![ZenVoich](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/zenvoich/32/5969_2.png) [@ZenVoich](https://forum.dfinity.org/u/ZenVoich)\
**Post date:** [May 30, 2023, 7:09am UTC](https://forum.dfinity.org/t/compatibility-error/20275/4 "2023-05-30T07:09:56Z")

</div>

I think it’s errored due to the removal of `#legacy : StableState;`. If you are sure there is no `#legacy` data you can upgrade w/o data loss.

Also there is error when you _add_ new variant, for example `#v2`, should not it be safe to upgrade in that case?

It would also be great to see all compatibility check errors.  
For example, if I am sure there is no `#legacy` data and remove it, but also if I change inner structure in `#v1` it will show the same error, so there is a chance that i will miss it and lose data.

---

<div class="post-metadata">

**Author:** ![claudio](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/claudio/32/322_2.png) [@claudio](https://forum.dfinity.org/u/claudio)\
**Post date:** [May 30, 2023, 10:03pm UTC](https://forum.dfinity.org/t/compatibility-error/20275/5 "2023-05-30T22:03:29Z")

</div>

I think it does matter.

If you have two stable variables that reference the same mutable array, they cannot safely upgrade to different types. Writing a value of the new type to one may be observed by reads from the other.

You can migrate a top-level stable var to a supertype, but it still has to be a supertype and mutable arrays are invariant so the only legal supertype is ‘Any’.

Note here that the content type of the mutable stable variable is itself mutable.

---

<div class="post-metadata">

**Author:** ![rossberg](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/rossberg/32/795_2.png) [@rossberg](https://forum.dfinity.org/u/rossberg)\
**Post date:** [May 31, 2023, 6:55am UTC](https://forum.dfinity.org/t/compatibility-error/20275/6 "2023-05-31T06:55:23Z")

</div>

Ah yes, good point about possible sharing.

---

<div class="post-metadata">

**Author:** ![cryptoschindler](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/cryptoschindler/32/26_2.png) [@cryptoschindler](https://forum.dfinity.org/u/cryptoschindler)\
**Post date:** [June 2, 2023, 5:47pm UTC](https://forum.dfinity.org/t/compatibility-error/20275/7 "2023-06-02T17:47:15Z")

</div>

> [@claudio](#):
>
> My hunch is this is because the arrays are mutable so the type inside cannot be changed at all.  
> Did any of the types reference from the mutable array element type change?

Yes, they did change. E.g. from

```auto
type StableChunk__1 =
  ?{
     #legacy : StableState__1;
     #v1 : {assetsChunk : [Asset]; assetsCount : Nat};
     #v1_chunk : {assetsChunk : [Asset]}
   };

```

to

```auto
type StableChunk__1 =
  ?{
     #v1 : {assetsChunk : [Asset]; assetsCount : Nat};
     #v1_chunk : {assetsChunk : [Asset]}
   };

```

What would be the best way to structure our data so that we can add new variants to `StableChunk__1` ?

And +1 to what @ZenVoich asked
