Updating existing product with the `productSet` mutation throws unexpected error, when `input.productOptions` using `linkedMetafield` and `input.metafields` are set at the same time

Using the GraphQL 2025-10 version to create and update a product using the productSet mutation, gives a strange error when trying to do the following.

  1. Create a new product using productSet with input.productOptions using a linkedMetafield and input.metafields with a custom metafield.

    mutation ProductSet {
      productSet(
        input: {
          title: "New product"
          category: "gid://shopify/TaxonomyCategory/hg-3-30"
          productOptions: [
            {
              name: "Color"
              linkedMetafield: {
                namespace: "shopify"
                key: "color-pattern"
                values: [
                  "gid://shopify/Metaobject/123456789012"
                  "gid://shopify/Metaobject/123456789013"
                ]
              }
            }
          ]
          variants: [
            {
              optionValues: {
                optionName: "Color"
                linkedMetafieldValue: "gid://shopify/Metaobject/123456789012"
              }
              price: 10
            }
            {
              optionValues: {
                optionName: "Color"
                linkedMetafieldValue: "gid://shopify/Metaobject/123456789013"
              }
              price: 15
            }
          ]
          metafields: [
            {
              namespace: "custom"
              key: "length"
              value: "{\"value\":10,\"unit\":\"cm\"}"
              type: "dimension"
            }
          ]
        }
      ) {
        userErrors {
          field
          message
        }
        product {
          id
          options {
            id
            name
            position
            values
            optionValues {
              id
              name
              hasVariants
            }
          }
          variants(first: 5) {
            nodes {
              id
              title
              price
              selectedOptions {
                name
                value
              }
            }
          }
        }
      }
    }
    

    This operation work fine and will return a new product with an ID.

  2. Next, I try to update the product with the same mutation and a few updated values

    mutation ProductSet {
      productSet(
        identifier: { id: "gid://shopify/Product/12345678901234" } # adding an identifier to update the existing product
        input: {
          title: "Updated product" # updating the title
          category: "gid://shopify/TaxonomyCategory/hg-3-30"
          productOptions: [
            {
              name: "Color"
              linkedMetafield: {
                namespace: "shopify"
                key: "color-pattern"
                values: [
                  "gid://shopify/Metaobject/123456789012"
                  "gid://shopify/Metaobject/123456789013"
                ]
              }
            }
          ]
          variants: [
            {
              optionValues: {
                optionName: "Color"
                linkedMetafieldValue: "gid://shopify/Metaobject/123456789012"
              }
              price: 10
            }
            {
              optionValues: {
                optionName: "Color"
                linkedMetafieldValue: "gid://shopify/Metaobject/123456789013"
              }
              price: 15
            }
          ]
          metafields: [
            {
              namespace: "custom"
              key: "length"
              value: "{\"value\":10,\"unit\":\"cm\"}"
              type: "dimension"
            }
          ]
        }
      ) {
        userErrors {
          field
          message
        }
        product {
          id
          options {
            id
            name
            position
            values
            optionValues {
              id
              name
              hasVariants
            }
          }
          variants(first: 5) {
            nodes {
              id
              title
              price
              selectedOptions {
                name
                value
              }
            }
          }
        }
      }
    }
    

    This will throw an error

    {
      "data": {
        "productSet": {
          "userErrors": [
            {
              "field": [
                "input"
              ],
              "message": "This metafield is connected to an option. To make changes, edit the option. Metafield Namespace: shopify, Metafield Key: color-pattern, Metafield Owner: Product"
            }
          ],
          "product": {
            ...
          }
        }
      },
      "extensions": {
        ...
      }
    }
    

I’ve tried the same operations, but leaving out the input.metafields, and the API works as expected.

  1. Create a new product using productSet with input.productOptions using a linkedMetafield, but NO input.metafields.

    mutation ProductSet {
      productSet(
        input: {
          title: "New product"
          category: "gid://shopify/TaxonomyCategory/hg-3-30"
          productOptions: [
            {
              name: "Color"
              linkedMetafield: {
                namespace: "shopify"
                key: "color-pattern"
                values: [
                  "gid://shopify/Metaobject/123456789012"
                  "gid://shopify/Metaobject/123456789013"
                ]
              }
            }
          ]
          variants: [
            {
              optionValues: {
                optionName: "Color"
                linkedMetafieldValue: "gid://shopify/Metaobject/123456789012"
              }
              price: 10
            }
            {
              optionValues: {
                optionName: "Color"
                linkedMetafieldValue: "gid://shopify/Metaobject/123456789013"
              }
              price: 15
            }
          ]
        }
      ) {
        userErrors {
          field
          message
        }
        product {
          id
          options {
            id
            name
            position
            values
            optionValues {
              id
              name
              hasVariants
            }
          }
          variants(first: 5) {
            nodes {
              id
              title
              price
              selectedOptions {
                name
                value
              }
            }
          }
        }
      }
    }
    
  2. Update the product with the same mutation

    mutation ProductSet {
      productSet(
        identifier: { id: "gid://shopify/Product/12345678901234" } # adding an identifier to update the existing product
        input: {
          title: "Updated product" # updating the title
          category: "gid://shopify/TaxonomyCategory/hg-3-30"
          productOptions: [
            {
              name: "Color"
              linkedMetafield: {
                namespace: "shopify"
                key: "color-pattern"
                values: [
                  "gid://shopify/Metaobject/123456789012"
                  "gid://shopify/Metaobject/123456789013"
                ]
              }
            }
          ]
          variants: [
            {
              optionValues: {
                optionName: "Color"
                linkedMetafieldValue: "gid://shopify/Metaobject/123456789012"
              }
              price: 10
            }
            {
              optionValues: {
                optionName: "Color"
                linkedMetafieldValue: "gid://shopify/Metaobject/123456789013"
              }
              price: 15
            }
          ]
        }
      ) {
        userErrors {
          field
          message
        }
        product {
          id
          options {
            id
            name
            position
            values
            optionValues {
              id
              name
              hasVariants
            }
          }
          variants(first: 5) {
            nodes {
              id
              title
              price
              selectedOptions {
                name
                value
              }
            }
          }
        }
      }
    }
    

    No errors thrown, so the API works as expected for the input.productOptions using a linkedMetafield, but for some reason not when we also add input.metafields.

Managed to get it working by defining the linkedMetafield in the input.metafields as well, so the full operation has to look like this now.

I do think it’s quite unintuitive to have to “duplicate” the data like that.

mutation ProductSet {
  productSet(
    input: {
      title: "New product"
      category: "gid://shopify/TaxonomyCategory/hg-3-30"
      productOptions: [
        {
          name: "Color"
          linkedMetafield: {
            namespace: "shopify"
            key: "color-pattern"
            values: [
              "gid://shopify/Metaobject/123456789012"
              "gid://shopify/Metaobject/123456789013"
            ]
          }
        }
      ]
      variants: [
        {
          optionValues: {
            optionName: "Color"
            linkedMetafieldValue: "gid://shopify/Metaobject/123456789012"
          }
          price: 10
        }
        {
          optionValues: {
            optionName: "Color"
            linkedMetafieldValue: "gid://shopify/Metaobject/123456789013"
          }
          price: 15
        }
      ]
      metafields: [
        {
          namespace: "custom"
          key: "length"
          value: "{\"value\":10,\"unit\":\"cm\"}"
          type: "dimension"
        }
        # We have to "duplicate" this here as well
        {
          namespace: "shopify"
          key: "color-pattern"
          value: "[\"gid://shopify/Metaobject/123456789012\",\"gid://shopify/Metaobject/123456789013\"]"
          type: "list.metaobject_reference"
        }
      ]
    }
  ) {
    userErrors {
      field
      message
    }
    product {
      id
      options {
        id
        name
        position
        values
        optionValues {
          id
          name
          hasVariants
        }
      }
      variants(first: 5) {
        nodes {
          id
          title
          price
          selectedOptions {
            name
            value
          }
        }
      }
    }
  }
}