Cannot access the field inventoryItem on ProductVariant

I’m creating a shopify app with a Checkout UI extension. This extension will run for each line item and perform a logic to display a flag notification.

I need to access the locations of each product to perform my validation logic. I’m using the below query:

  query GetProductLocations($productId: ID!) {
    product(id: $productId) {
      variants(first: 10) {
        nodes {
          inventoryItem {
            inventoryLevels(first: 10) {
              edges {
                node {
                  location {
                    id
                    name
                  }
                  available
                }
              } 
            }
          }
        }
      }
    }
  }

But, when I run this query using fetch, I’m receiving the error '“Field ‘inventoryItem’ doesn’t exist on type ‘ProductVariant’”.

Accordingly with the documentation (ProductVariant - GraphQL Admin), the field exists in API version 2025-04.

What can I do?

Do you have permissions to read products and inventory? :thinking:

Yeah, I defined the access scopes on TOML file:
image

Can you confirm what URL you’re using in the request? Is it definitely for the Admin API? And not the Storefront API?

That was the problem @Luke, thank you!

I was using a query to the Admin API, but doing the request to the Storefront API. I think that I cannot make requests to the Admin API on a Checkout UI extension, so I change my query to use the Storefront API:

  query GetProductLocations($productId: ID!) {
    product(id: $productId) {
      handle,
      selectedOrFirstAvailableVariant {
        title,
        currentlyNotInStock,
        quantityAvailable,
        storeAvailability(first: 10) {
          nodes {
            available,
            quantityAvailable,
            location {
              name,
              id
            }
          }
        }
      }
    }
  }

It’s not the same information, but I think I can solve my problem with this query.

Nonetheless, I can’t run this query in my app extension. I defined all the necessary scopes (below image), installed the app in the store, then the access scopes are prompted correctly and I approve the access.

[access_scopes]
# Learn more at https://shopify.dev/docs/apps/tools/cli/configuration#access_scopes
scopes = "unauthenticated_read_product_pickup_locations,unauthenticated_read_product_listings,unauthenticated_read_product_inventory"

But when I go to the checkout, add the block app and try to run the preview, I receive an unauthorized error:

“Access denied for quantityAvailable field. Required access: unauthenticated_read_product_inventory access scope.”

“Access denied for storeAvailability field. Required access: unauthenticated_read_product_pickup_locations access scope.”

What I’m doing wrong? All these scopes are defined in TOML file.

Just wanted to second this. Im getting the same issue as well in my checkout extension. I have also confirmed I have the unauthenticated_read_product_inventory access scope set and approved on the admin side

Hey folks,
I think there is some confusion here.

There is the Shopify Admin API, which has scopes such as read_products, read_inventory etc. This is where you can get granular inventory information out for example inventoryLevels on the inventory item on a product variant ProductVariant - GraphQL Admin and generally manage and administrate information.

Then there seperatly the Shopify Storefront API, this is designed to be used on the frontend of a site / app or hydrogen site for example. This has access scopes beginning with unauthenticated_ and a much highier rate limit.
This has a separate set of queries which can be run from the Admin and its designed for a different use case.
You can still access some inventory information ProductVariant - Storefront API
But as you can understand it won’t give you the same granularity as the Admin API because otherwise it would expose too much inventory info publically.

You need to choose the right API for you use case, or you can use both if it makes sense to do so.
You will need to request access scopes to both if you need it though, you don’t get storefront API permissions for example because you have read_inventory on the Admin as they are seperate things.

Hey Jordan, thank you for the detailed response! As for the latter part of the thread, the issue mentioning the permissions seems to not be a problem with where to get the inventory info but more of the GQL query throwing a permissions error even after that scope has been added and granted

Ah sorry missed that bit, do you have an example of the code you are using to run the query if possible please?

Here is that sample query:

query getProducts($id: ID!) {
 product(id: $id) {
   tags
   totalInventory
   variants(first: 10) {
     nodes {
       id
       quantityAvailable
     }
   }
   id
   title
 }
}

I have also confirmed that I have accepted the unauthenticated_read_product_inventory and I am hitting the storefront API. Also this is coming from a Checkout UI extension.

Thank you again for your time!

Sorry I mean do you have more of the code? How you are running the query?
Is the product visible on the Online Store channel?

Ah sorry,

const { data, errors } = await query(
                `query getProducts($id: ID!) {
                product(id: $id) {
                tags
                totalInventory
                variants(first: 100) {
                     nodes {
                        id
                        sku
                        quantityAvailable
                      }
                }
                      id
                      title
                    }
                }`,
                {
                    variables: { id: productId },
                }
            )

Where the ‘query’ is the storefront method in checkout extensions Storefront API

And yeah it is visible, also I think it would be throwing a different error if it wasn’t visible, right?