Editable Grid Tokens Issue

I've followed the SAIL Recipe for creating an editable grid and I'm having an issue with the tokens being stored as a list of CDT's instead of List Dictionary type.  The issue it creates comes from removing and adding values to actual CDT array (the error is related to size of token array being shorter than the CDT array).  I've tried setting the items token to initial CDT Array too, but after adding and removing data from the CDT array's data gets screwed up.  This has happened on more than one occasion with different grids that were created following the recipe almost verbatim.  Other times it works fine.  Is there a reason why the token wouldn't be properly initialized by the a!applyComponents() or why using addRowLink in the grid would cause the token to be saved as an array of CDT?

editable grid:

load(
  local!itemsToken,
    a!gridLayout(
      totalCount: count(ri!gateType),
      headerCells:{
        a!gridLayoutHeaderCell(label: "ID", align: "RIGHT"),
        a!gridLayoutHeaderCell(label: "Value"),
        a!gridLayoutHeaderCell(label: "Type"),
        a!gridLayoutHeaderCell(label: "Order", align: "RIGHT"),
        a!gridLayoutHeaderCell(label: "isActive"),
        /* For the "Remove" column*/
        a!gridLayoutHeaderCell(label: "")
      },
      columnConfigs: {
        a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 1),
        a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 8),
        a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 5),
        a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 2),
        a!gridLayoutColumnConfig(width: "DISTRIBUTE", weight: 2),
        a!gridLayoutColumnConfig(width: "ICON")
      },
      rows: a!applyComponents(
        function: rule!PMT_GateTypesRowItemEach(
          gateType: ri!gateType,
          itemsToken: local!itemsToken,
          index: _,
          deletedItemsId: ri!deletedItemsId
        ),
        array: if(or(isnull(ri!gateType), count(ri!gateType) < 1), {}, 1+enumerate(count(ri!gateType))),
        arrayVariable: local!itemsToken
      ),
      addRowlink: a!dynamicLink(
        label: "Add Item",
        /*
         * For your use case, set the value to a blank instance of your CDT using
         * the type constructor, e.g. type!PurchaseRequestItem(). Only specify the field
         * if you want to give it a default value e.g. due: today()+1.
         */
        value: 'type!{urn:com:appian:types:PMT}PMT_GateType'(),
        saveInto: {
          a!save(ri!gateType, append(ri!gateType, save!value)),
          /* When modifying the size of the array used in a!applyComponents, */
          /* make the same change in the "token" array variable              */
          a!save(local!itemsToken, append(local!itemsToken, save!value))
        }
      )
    )
)

row expression:

a!gridRowLayout(
  selectionDisabled: true(),
  id: ri!index,
  contents: {
    a!textField(
      label: "id"  & ri!index,
      disabled: true(),
      value: ri!gateType[ri!index].id
    ),
    a!textField(
      label: "value" & ri!index,
      value: ri!gateType[ri!index].value,
      saveInto:  ri!gateType[ri!index].value
    ),
    a!textField(
      label: "type" & ri!index,
      value: ri!gateType[ri!index].type,
      saveInto:  ri!gateType[ri!index].type
    ),
    a!textField(
      label: "order" & ri!index,
      value: ri!gateType[ri!index].order,
      saveInto:  ri!gateType[ri!index].order
    ),
    a!dropdownField(
      label: "isActive" & ri!index,
      placeholderLabel: "-- Select --",
      choiceLabels: {"Yes", "No"},
      choiceValues: {true(), false()},
      value: ri!gateType[ri!index].isActive,
      saveInto: ri!gateType[ri!index].isActive
    ),
    a!imageField(
      label: "delete " & ri!index,
      images: a!documentImage(
        document: a!iconIndicator("REMOVE"),
        altText: "Remove",
        caption: "Remove " & ri!gateType[ri!index].value,
        link: a!dynamicLink(
          value: ri!index,
          saveInto: {
            a!save(ri!deletedItemsId, append(ri!deletedItemsId, ri!gateType[ri!index].id)),
            a!save(ri!gateType, remove(ri!gateType, save!value)),
            a!save(ri!itemsToken, remove(ri!itemsToken, save!value))
          }
        )
      ),
      size: "ICON"
    )
  }
)

This is supposed to be the format of one item in the token (this is the format from another editable grid that works):

[id:,projectId:,gateId:,isDelivery:,milestone:[id=, value=, isActive=, order=, type=],endDate:,baselineId:,approvedDate:4/27/2017,["evaluatedui" 0 "evaluatedui" 1 "designerwrapper_main" "with" 2 "with" 5 "expd_sailappmain" "load" 2 "expd_sailruledesigner" "target" "expd_designermain" "load" "with" 0 "load" 0 "load" "with" 2 "evaluated" "expd_designereval" 0 ["evaluatedui" 0 "evaluatedui" 1 "designerwrapper_main" "with" 2 "with" 5 "expd_sailappmain" "load" 2 "expd_sailruledesigner" "target" "expd_designermain" "load" "with" 0 "load" 0 "load" "with" 2 "evaluated" "expd_designereval" 0] "l" 0 "evalresult" "evaluatedui" 0 0 "result" 2 "load" 2 "rows" "applycomponents" 2 2 "load" "with" "l" 0 "pmt_milestoneitemroweach" "contents" 0 "dummy_bs"]:[milestoneOptions:[id=1, value=Preplanning, isActive=true, order=1, type=1]; [id=2, value=Planning Meeting, isActive=true, order=2, type=1]; [id=3, value=SRR, isActive=true, order=3, type=1]; [id=4, value=Initial SCCSB, isActive=true, order=4, type=1]; [id=5, value=Planning Complete, isActive=true, order=5, type=1],readOnly:false],["evaluatedui" 0 "evaluatedui" 1 "designerwrapper_main" "with" 2 "with" 5 "expd_sailappmain" "load" 2 "expd_sailruledesigner" "target" "expd_designermain" "load" "with" 0 "load" 0 "load" "with" 2 "evaluated" "expd_designereval" 0 ["evaluatedui" 0 "evaluatedui" 1 "designerwrapper_main" "with" 2 "with" 5 "expd_sailappmain" "load" 2 "expd_sailruledesigner" "target" "expd_designermain" "load" "with" 0 "load" 0 "load" "with" 2 "evaluated" "expd_designereval" 0] "l" 0 "evalresult" "evaluatedui" 0 0 "result" 2 "load" 2 "rows" "applycomponents" 2 2 "load" "with" "l" 0 "pmt_milestoneitemroweach" "contents" 1 "datefield"]:[textValue:,validations:]]

  Discussion posts and replies are publicly visible