Device Tutorial Migration V2 -> V3 does not work for me

I’m trying to migrate devices from V2 to V3
first of all I copied device app/device/and key from V2 to V3 and then changed key on V2 so device won’t be able to join on V2. device reset but never joined V3

So I decided to follow official documentation tutorial for about 2H and it still not working so I put back my device in V2, device is seen (on V2) and sending data so let’s explain an reproduce the issue in case someone will be able to help.
I’m using latest ttn-lw-migrate as today, and since community stack is below V3.12 I prepared as stated here with

--ttnv2.with-session=false

But note this is not in sync with tutorial that state that if backend version is 3.10 or higher we can migrate keeping session.

So here we go (I masked keys by * all below)

./ttn-lw-migrate devices  --ttnv2.with-session=false --source ttnv2 "mercury-16" >mercury16.json 
  INFO Clearing device keys  dev_eui=****** device_id=mercury-16

now looks into JSON file (I pretty printed for easier reading)

{
  "ids": {
    "device_id": "mercury-16",
    "application_ids": {
      "application_id": "enviro-dev"
    },
    "dev_eui": "****",
    "join_eui": "****"
  },
  "created_at": "0001-01-01T00:00:00Z",
  "updated_at": "0001-01-01T00:00:00Z",
  "name": "mercury-16",
  "lorawan_version": "1.0.2",
  "lorawan_phy_version": "1.0.2-b",
  "frequency_plan_id": "EU_863_870_TTN",
  "supports_join": true,
  "root_keys": {
    "app_key": {
      "key": "*****"
    }
  },
  "mac_settings": {
    "supports_32_bit_f_cnt": true,
    "status_time_periodicity": "0s",
    "status_count_periodicity": 0
  },
  "mac_state": {
    "current_parameters": {
      "max_eirp": 16,
      "adr_nb_trans": 1,
      "rx1_delay": 1,
      "rx2_data_rate_index": 3,
      "rx2_frequency": "869525000",
      "ping_slot_frequency": "869525000",
      "channels": [
        {
          "uplink_frequency": "868100000",
          "downlink_frequency": "868100000",
          "max_data_rate_index": 5,
          "enable_uplink": true
        },
        {
          "uplink_frequency": "868300000",
          "downlink_frequency": "868300000",
          "max_data_rate_index": 5,
          "enable_uplink": true
        },
        {
          "uplink_frequency": "868500000",
          "downlink_frequency": "868500000",
          "max_data_rate_index": 5,
          "enable_uplink": true
        },
        {
          "uplink_frequency": "867100000",
          "downlink_frequency": "867100000",
          "max_data_rate_index": 5,
          "enable_uplink": true
        },
        {
          "uplink_frequency": "867300000",
          "downlink_frequency": "867300000",
          "max_data_rate_index": 5,
          "enable_uplink": true
        },
        {
          "uplink_frequency": "867500000",
          "downlink_frequency": "867500000",
          "max_data_rate_index": 5,
          "enable_uplink": true
        },
        {
          "uplink_frequency": "867700000",
          "downlink_frequency": "867700000",
          "max_data_rate_index": 5,
          "enable_uplink": true
        },
        {
          "uplink_frequency": "867900000",
          "downlink_frequency": "867900000",
          "max_data_rate_index": 5,
          "enable_uplink": true
        }
      ],
      "adr_ack_limit_exponent": {
        "value": 6
      },
      "adr_ack_delay_exponent": {
        "value": 5
      },
      "ping_slot_data_rate_index_value": {
        "value": 3
      }
    },
    "desired_parameters": {
      "max_eirp": 16,
      "adr_nb_trans": 1,
      "rx1_delay": 1,
      "rx2_data_rate_index": 3,
      "rx2_frequency": "869525000",
      "ping_slot_frequency": "869525000",
      "channels": [
        {
          "uplink_frequency": "868100000",
          "downlink_frequency": "868100000",
          "max_data_rate_index": 5,
          "enable_uplink": true
        },
        {
          "uplink_frequency": "868300000",
          "downlink_frequency": "868300000",
          "max_data_rate_index": 5,
          "enable_uplink": true
        },
        {
          "uplink_frequency": "868500000",
          "downlink_frequency": "868500000",
          "max_data_rate_index": 5,
          "enable_uplink": true
        },
        {
          "uplink_frequency": "867100000",
          "downlink_frequency": "867100000",
          "max_data_rate_index": 5,
          "enable_uplink": true
        },
        {
          "uplink_frequency": "867300000",
          "downlink_frequency": "867300000",
          "max_data_rate_index": 5,
          "enable_uplink": true
        },
        {
          "uplink_frequency": "867500000",
          "downlink_frequency": "867500000",
          "max_data_rate_index": 5,
          "enable_uplink": true
        },
        {
          "uplink_frequency": "867700000",
          "downlink_frequency": "867700000",
          "max_data_rate_index": 5,
          "enable_uplink": true
        },
        {
          "uplink_frequency": "867900000",
          "downlink_frequency": "867900000",
          "max_data_rate_index": 5,
          "enable_uplink": true
        }
      ],
      "adr_ack_limit_exponent": {
        "value": 6
      },
      "adr_ack_delay_exponent": {
        "value": 5
      },
      "ping_slot_data_rate_index_value": {
        "value": 3
      }
    },
    "lorawan_version": "1.0.2"
  }
}

now use import tool v0.4.0-rc1, the application is already created and already have some devices working


./ttn-lw-cli end-devices create --application-id "enviro-dev" < mercury16.json
error:pkg/ttnpb:parse (could not parse `{"value":6}` into `ADRAckLimitExponent`)
    field=ADRAckLimitExponent
    value={"value":6}
--- strconv.ParseInt: parsing "{\"value\":6}": invalid syntax

Looks like export/import are not in sync I even tried old export v0.2.0-rc2 without any success
What step did I missed?

I don’t think you did - the error message is about the reading the JSON file and turning it in to yet another data structure language that’s not YAML but Google Protocol Buffers that’s like XML but not, defined in yet another definition language that then creates source code in your language of choice to do things like parsing incoming data, picking out the values you want, packing it up for transmission or storage etc etc

The migration tool & the cli app pulls in definitions from the live dev repro of the main v3 stack. So it’s currently entirely feasible at any current point in time for the migration tool, the main cli app and the v3 stack to not quite join up its dots given the number of opaque layers between the definitions in the v3 stack all the way through to generated code parsing JSON in the cli app that was generated by the migration tool that was looking at the definitions on a different day …

If you care to file a GitHub issue as that’s the only way the dev’s will get to know about this. I’ve started working the migration tool in my plans so I can have a stab at it and add to it.

In the meanwhile, I think we need to let things cook a bit more before we use these tools in anger.