Discount Function InputQuery data doesn't match GraphQL app Data

Topic summary

Main issue: Metafield data was available in a Shopify Function’s InputQuery for a discount (via discountNode.metafield), but querying discountNodes via the Admin GraphQL API returned empty metafields.

Context: Metafields are key–value data identified by namespace/key. The InputQuery (Shopify Functions runtime) returned the expected JSON for the discount configuration. However, the Admin GraphQL query (discountNodes { metafields { … } }) showed no metafield nodes.

Initial guidance: Ensure the query specifies the exact namespace/key and requests the metafield value. Also confirm the metafield is actually associated to the discount node.

Root cause: The metafields were created using a namespace starting with “$app:” (e.g., “$app:volume-discount”). This prevented association to the discount node for Admin GraphQL retrieval.

Fix: Replace the “$app:” namespace with a custom, app-specific namespace, e.g., “${appId}-discount-group”. After doing so, the discount nodes returned metafields correctly via Admin GraphQL.

Outcome: Resolved. Actionable notes:

  • Avoid “$app:” in metafield namespaces when creating via Admin API.
  • Use a stable, app-specific namespace and query by exact namespace/key including the value field.
Summarized with AI on January 9. AI used: gpt-5.

I’m trying to build a discount function that will apply a different discount based on customer tags. I’m trying to figure out how to do it with the app metafield but I can’t seem to get the metafield data through the GraphQL app.

Here’s what’s going on, here’s my Discount Function’s InputQuery

query RunInput {
  cart {
    buyerIdentity{
      customer{
        id,
        hasAnyTag
      }
    }
    lines {
      quantity
      merchandise {
        __typename
        ...on ProductVariant {
          id
        }
      }
    }
  }
  discountNode {
    metafield(namespace: "$app:volume-discount", key: "function-configuration") {
      value,
    }
  }
}

That works perfectly well and yields the data from the discount I created in the admin UI:

{
  "customer_tag": "new-customer",
  "excluded_products": "",
  "amount": 20,
  "percentage": true
}

But in using the Shopify GraphQL app, if I put in this query:

query MyQuery {
  discountNodes(first: 5) {
    nodes {
      metafields(first: 1) {
        nodes {
          key
          namespace
        }
      }
      id
      discount {
        ... on DiscountAutomaticApp {
          title
        }
      }
    }
  }
}

I get this output:

{
  "data": {
    "discountNodes": {
      "nodes": [
        {
          "metafields": {
            "nodes": []
          },
          "id": "gid://shopify/DiscountAutomaticNode/1438023254326",
          "discount": {
            "title": "Third Test"
          }
        },
        {
          "metafields": {
            "nodes": []
          },
          "id": "gid://shopify/DiscountAutomaticNode/1438842224950",
          "discount": {
            "title": "October 17"
          }
        }
      ]
    }
  },
  "extensions": {
    "cost": {
      "requestedQueryCost": 27,
      "actualQueryCost": 11,
      "throttleStatus": {
        "maximumAvailable": 1000,
        "currentlyAvailable": 989,
        "restoreRate": 50
      }
    }
  }
}

Can anybody tell me why there’s no metafield data for these items when I can pull it from in the InputQuery?

Hi Cmoriarty83,

The issue you’re experiencing might be due to the fact that the GraphQL query you’re using doesn’t specifically request for the value field within the metafields field. When querying metafields, you need to specify the namespace and key the metafield you’re looking for, and also include the value field in your query to get the actual data stored in the metafield.

If this doesn’t solve your problem, it might be that the metafields aren’t associated with the discount nodes you’re querying. In that case, you’ll need to ensure that the metafields are correctly attached to the discount nodes.

Hope this helps!

Thanks for your reply Liam. I know that I need to provide specific namespace and key when getting a metafield. I think the problem is that I’m not correclty associating the discount node with the metafield. Here’s the mutation I’m using:

const response = await admin.graphql(
			`#graphql
          mutation CreateAutomaticDiscount($discount: DiscountAutomaticAppInput!) {
            discountCreate: discountAutomaticAppCreate(automaticAppDiscount: $discount) {
              userErrors {
                code
                message
                field
              }
            }
          }`,
			{
				variables: {
					discount: {
						...baseDiscount,
						metafields: [
							{
								namespace: "$app:volume-discount",
								key: "function-configuration",
								type: "json",
								value: JSON.stringify({
									customer_tag: configuration.customer_tag,
									excluded_products: configuration.excluded_products,
									amount: configuration.amount,
									percentage: configuration.percentage,
								}),
							},
						],
					},
				},
			}
		);

I think the problem is with the use of the namespace: “$app:volume-discount”. I found that if I switch this to a simple string like “discount-group” my discount nodes become correctly associated with the metafields in my graphql queries. Can you explain how I seem to be short circuiting things with the $app. in the namespace? Thanks so much!

how did you solve it?

the issue was the namespace. Using “$app:” was made it so the meta fields weren’t getting associated with the discount or something. I just saved the my app id to a variable and the used a string literal, eg, ‘${appId}-discount-group’ and that seemed to do the trick.