Why is my GraphQL query not showing metafield for all products?

Topic summary

Issue: A user’s GraphQL query retrieves metafield IDs for some products but not for others where the metafield hasn’t been initialized with a value. They need the metafield ID to update it via the productUpdate mutation.

Solution provided:

  • Metafields cannot exist without being initialized, so they won’t have IDs until created
  • Instead of querying metafields as arrays (edges/node), use direct querying: metafield(namespace: "global", key: "example") which returns null if non-existent
  • Create metafields directly within the productUpdate mutation if they don’t exist
  • Pass metafields array in the mutation input with namespace, key, type, and value
  • Existing metafields can be updated by passing their ID; new ones are created automatically

Related issue: Another user reports they can update existing metafields on customerUpdate using the metafield ID but cannot create new ones using the same approach, seeking additional insights.

Summarized with AI on November 8. AI used: claude-sonnet-4-5-20250929.

Hello i have following Issue,

I want to get the metafield id of my sold_out_metafield to change its value in the productUpdate Mutation. My Problem is that this query is showing the metafield for some products but not for products where the metafield is not initialized with a value. How can i get the id of this metafield to set the value? or how can i initially set the value to an empty value so every id is initialized.

 data = {
      "query": `query {
  products(first: 10, after:"${cursor}",query:"(product_type:bundle)") {
    pageInfo {
      hasNextPage
      endCursor
    }
    edges {
      node {
        id
        title
        tags
        variants(first: 1){
          edges{
            node{
              id
              inventoryItem{
                id
                tracked
                    inventoryLevels(first:1){
                      edges{
                        node{
                          location{
                            id
                          }
                        }
                      }
                }
                
              }
            }
          }
        }
        metafields(first: 1,namespace:"bundle"){
          edges{
            node{
              value
              key
              namespace
            }
          }
        }
        sold_out_metafield:metafields(first: 1,namespace:"sold_out"){
          edges{
            node{
              id
            }
          }
        }
      }
    }
  }
}`
,
}
      }

      let response = await axios($, {
      method: "post",
      url: `https://${this.shopify_developer_app.$auth.shop_id}.myshopify.com/admin/api/2023-04/graphql.json`,
      headers: {
        "X-Shopify-Access-Token": `${this.shopify_developer_app.$auth.access_token}`,
        "Content-Type": `application/json`,
      },
      data,
    })

Empty Metafield Response (showing only on some products):

Expected Response:

Hi @Erik_Abrio ,

First of all, a little tips when you get specific metafield on an object.

You can query it like this :

{customer(id: "gid://shopify/Customer/2554556556556"){
    id
    example_metafield: metafield(namespace: "global", key: "example") {
        id 
        key
        namespace
        value 
    }
}}

With this version, you avoid to get the content inside an array (edges, node).

If the metafield doesn’t exists, the value of the example_metafield will be null in the result.

A metafield cannot exist if it’s not initialized, so cannot have ID.

You can create the metafield directly in the product update mutation if it doesn’t exist.

Here is an example from the Shopify doc.

You can see below the content of the input for the productUpdate mutation (but it works for all object that can accept metafields).

"metafields": [
      {
        "namespace": "my_field",
        "key": "liner_material",
        "type": "single_line_text_field",
        "value": "Synthetic Leather"
      },
      {
        "id": "gid://shopify/Metafield/1069229034",
        "value": "Rubber"
      }
]

Here the metafield my_field.liner_material is created and the second metafield is updated with a new value just by passing it’s ID.

Hope it’s help you.

I can’t get this to work on customerUpdate. This is what I’m trying to do:

"""
mutation {
    customerUpdate(input:{
                id:"%s",
                metafields: {
                namespace:"custom",
                key:"value",
                type: "single_line_text_field",
                value:"%s",}
                }){
        customer {
            id
            firstName
            
            }
        userErrors{
            field
            message
            }    
        }
}
"""%(custID, value)

I can get and use the metafield id to update a metafield that’s already set but it won’t create a new one. Any insights if you happen to see this would be appreciated.