Cannot change metaobject field type via app configuration — “existing metafield definition” error persists even after removing the field

Problem

I’m trying to change a field on a metaobject definition that is managed by my app’s shopify.app.toml configuration. For example, suppose I have the following definition:

[metaobjects.app.author.fields] 
name = { name = "name", type = "single_line_text_field", required = true } 
comment = { name = "comment", type = "single_line_text_field", required = true } ​

I want to change the comment field from single_line_text_field to a different type (e.g. multi_line_text_field or a metaobject_reference).

When I update the toml and run shopify app deploy, I get the following error:

Version couldn’t be created.

[metaobjects.app.author.fields.comment] Cannot change type of existing metafield definition - type: single_line_text_field

What I tried

I understand that Shopify does not allow changing the type of an existing metafield/metaobject field definition in place, so I tried a workaround:

  1. Remove the comment field entirely from the toml and deploy a new app version.
  2. Re-add the field with the new type and deploy again.

However, step 2 still fails with the same error referring to existing metafield definition - type: single_line_text_field. This is confusing, because after step 1 I would expect the old field definition to no longer exist — yet the deploy is still treating it as if the old single_line_text_field definition is still there.

I also tried deleting the metaobject definition directly via the Admin GraphQL API using metaobjectDefinitionDelete, but it returns the following error.

  "data": {
    "metaobjectDefinitionDelete": {
      "deletedId": null,
      "userErrors": [
        {
          "field": [
            "id"
          ],
          "message": "Definition is managed by app configuration and cannot be modified through the API.",
          "code": "APP_CONFIG_MANAGED"
        }
      ]
    }
  }

My questions:

  1. Why does the deploy still complain about an “existing metafield definition” of type single_line_text_field even after I removed the field from the toml and deployed successfully? Does removing a field from the toml not actually delete the underlying definition?
  2. What is the correct procedure to change the type of a field on an app-managed metaobject definition? Is there any supported way (CLI command, API, or Partner Dashboard action) to drop the old field/definition so I can recreate it with a new type?
  3. If the only path is to recreate the metaobject definition under a new key (e.g. author_v2) and migrate data, could you confirm that?

BTW: I think this is somewhat related to https://community.shopify.dev/t/cannot-change-app-metafield-type-from-number-integer-to-single-line-text-field-how-to-delete-and-recreate/26521

Hey @shunten31 - thanks for reaching out. Looking into this on my end here, I’ll loop back with you once I can confirm expected behaviour for you :slight_smile:

Hello, I have the same issue. I hope it can be fixed. Thanks.

Update on this: the behaviour you’ve reported does appear to be a current platform limitation. We’re exploring improving this however - to help us evaluate investment in support for this, can you describe usecases or benefits this would unlock?

Thanks for the update @Liam-Shopify!. I think supporting this would unlock a lot of value for apps that heavily rely on metaobjects/metafields and already have large merchant installations.

Shopify already allows certain definition type migrations in some directions via Admin and the Admin API (for example single_line_text_fieldmulti_line_text_field, or integer → decimal), so there is already precedent for controlled type evolution.

The main issue for app-managed definitions is operational risk. When an app has thousands of merchants and a field type needs to evolve as the product matures, the current workaround requires:

  1. Creating a brand new field or definition
  2. Migrating all merchant data
  3. Updating all application logic and storefront/admin references
  4. Handling backwards compatibility during rollout
  5. Cleaning up deprecated fields later

That process is significantly more risky and error-prone than a supported type migration path, especially for large production apps.

In many cases the underlying data is still conceptually compatible, but developers are forced into full migrations because the original definition becomes permanently locked. Supporting safe migrations for compatible type changes would reduce maintenance burden, lower merchant disruption, and make app-managed metaobjects much easier to evolve over time.

The current behaviour is also a bit confusing because removing the field from TOML and redeploying still leaves the original definition effectively reserved/persisted, which makes iterative schema evolution difficult.

Thanks @Liam-Shopify for clarifying!

To clarify my use case and add a suggestion:

Use case

In my case, I have a counseling_reservation metaobject which includes a single_line_text_field called room (containing a room name). I want to change this to a metaobject_reference and introduce a separate metaobject definition for rooms — I realized that referencing a dedicated room metaobject is better than keeping the room as a plain string.

@muchisx suggested type evolution for compatible types (e.g. single_line_text_fieldmulti_line_text_field), but my focus is a bit different. single_line_text_field and metaobject_reference are not compatible types, so I understand that an in-place type change is not possible.

The problem for me is that I cannot reuse the field name room ever again with a different field type. I’d like to be able to reuse field names for completely different types.

I understand this is not trivial, because existing metaobject entries already hold text data under room, for example:

{ title: "Reservation with Alice", room: "Room1" } 
{ title: "Reservation with Bob",   room: "Room2" }

My suggestion

It would be great to have a mutation like metaobjectDefinitionFieldRename.

Such a mutation would unblock this scenario by renaming an existing field on a metaobject definition — for example:

​ metaobjectDefinitionFieldRename(definition: "app--<uid>--counseling_reservation",   from: "room",   to: "room_name" )

This would rename the field on existing metaobject entries along with the definition:

​{ title: "Reservation with Alice", room_name: "Room1" } 
{ title: "Reservation with Bob",   room_name: "Room2" } ​

After that, I could freely add a new room field of type metaobject_reference in shopify.app.toml without a name collision, and migrate data from room_name to room at my app’s own pace.

We are also facing the same issue. As @muchisx mentioned, the current workaround is more error-prone. Is there any fix coming soon ?