Auto-generated migration moves fieldsets above root fields

When running an auto-generated migration script to add new models, we always see the field order end up different to the source environment used when generating the migration script. It looks like fieldsets are always created first, which makes sense, but then the field order is not updated.

To reproduce:

  1. Fork an environment
  2. Add a new data model
  3. Add a field to the model without putting it in a fieldset (e.g. a Title field)
  4. Create a fieldset and add a field to it
  5. Generate a migration script from the forked environment
  6. Run the migration on a second fork and compare the data models

Expected: The models would the same
Actual: The root (title) field appears below the fieldset

Not a big deal, but means we have to create a second migration script to re-order the fields.

Thanks for the report, @james1! I’ve made a ticket for it internally and will let you know as soon as we hear back.

Hey @james1, maybe I’m missing something, but by following your steps I get this, which is actually putting the field inside the fieldset.

Are you on the latest version of our CLI?

datocms --version                                                              
@datocms/cli/2.0.0 darwin-arm64 node-v16.20.0

Here’s my migration:

import { Client, SimpleSchemaTypes } from "@datocms/cli/lib/cma-client-node";

export default async function (client: Client) {
  console.log("Create new models/block models");

  console.log('Create model "Foobar" (`foobar`)');
  await client.itemTypes.create(
      id: "Kf7IE027RPeFW5tFsnxoMQ",
      name: "Foobar",
      api_key: "foobar",
      collection_appearance: "table",
      inverse_relationships_enabled: false,
      skip_menu_item_creation: true,
      schema_menu_item_id: "FI6ZSpOaSHWRaJyeMjiE1A",

  console.log("Creating new fields/fieldsets");

  console.log('Create fieldset "Gruppo" in model "Foobar" (`foobar`)');
  await client.fieldsets.create("Kf7IE027RPeFW5tFsnxoMQ", {
    id: "ejwHeyWyReKMb3DYAWkdAQ",
    title: "Gruppo",

    'Create Single-line string field "Title" (`title`) in model "Foobar" (`foobar`)'
  await client.fields.create("Kf7IE027RPeFW5tFsnxoMQ", {
    id: "JYYpdp0cTfaJpQMrv_rUmQ",
    label: "Title",
    field_type: "string",
    api_key: "title",
    appearance: {
      addons: [],
      editor: "single_line",
      parameters: { heading: false },
    default_value: "",
    fieldset: { id: "ejwHeyWyReKMb3DYAWkdAQ", type: "fieldset" },

  console.log("Finalize models/block models");

  console.log('Update model "Foobar" (`foobar`)');
  await client.itemTypes.update("Kf7IE027RPeFW5tFsnxoMQ", {
    title_field: { id: "JYYpdp0cTfaJpQMrv_rUmQ", type: "field" },

  console.log("Manage menu items");

  console.log('Create menu item "Foobar"');
  await client.menuItems.create({
    id: "f58iRiWSRg2LdlG5EE7hOQ",
    label: "Foobar",
    item_type: { id: "Kf7IE027RPeFW5tFsnxoMQ", type: "item_type" },


I probably didn’t explain it clearly enough. The problem was actually about the field that isn’t in the fieldset always appearing at the bottom of the field list.

So if I create this structure in the CMS:

  • Title (Text Field)
  • Group (Fieldset)
    • Field In Group (Text Field)

…and create a migration from it, after running the migration the structure becomes:

  • Group (Fieldset)
    • Field In Group (Text Field)
  • Title (Text Field)

It seems that all the fieldsets get created first, followed by any other ‘root’ fields.

The workaround is to then create a 2nd migration that only re-orders fields.

I see. Thanks for explaining, will look into that!

Should be fixed in v2.0.1 of our CLI!

1 Like