Product query sku filter not working properly

I need to filter all products with no SKU set. Using -sku:* isn’t working properly and fails to return some products that have variants with a null SKU.

Running the following queries produces no results:

x-request-id: 271998b6-518d-4df8-b292-881578105614-1783992234

{
    products(query:"-sku:*", first:10) {
        nodes {
            id
            title
            variants(first:10) {
                nodes {
                    id
                    title
                    inventoryItem {
                        sku
                    }
                }
            }

        }
     }
}

x-request-id: a69bd0f9-f226-4b8a-80bf-304124347f35-1783992200

query {
  productsCount(query: "-sku:*") {
    count
    precision
  }
}

x-request-id: 47972fe5-0bb3-42d7-a670-c5807d118955-1783992282

{
    productVariants(query:"-sku:*", first:10) {
        nodes {
            id
            title
            inventoryItem {
                sku
            }
        }
     }
}

Even though the following product ID is one example with variants that have a null SKU:

{
    product(id:"gid://shopify/Product/15851419369804") {
            id
            variants(first:10) {
                nodes {
                    id
                    inventoryItem {
                        sku
                    }
                }
            }
     }
}

Returns the result:

{
    "data": {
        "product": {
            "id": "gid://shopify/Product/15851419369804",
            "variants": {
                "nodes": [
                    {
                        "id": "gid://shopify/ProductVariant/57921697186124",
                        "inventoryItem": {
                            "sku": "[redacted]"
                        }
                    },
                    {
                        "id": "gid://shopify/ProductVariant/57921697153356",
                        "inventoryItem": {
                            "sku": "[redacted]"
                        }
                    },
                    {
                        "id": "gid://shopify/ProductVariant/57922056356172",
                        "inventoryItem": {
                            "sku": null
                        }
                    },
                    {
                        "id": "gid://shopify/ProductVariant/57922056388940",
                        "inventoryItem": {
                            "sku": null
                        }
                    }
                ]
            }
        }
    }
}

Is it related to this issue? productVariants's sku search prefix bug

Those exact variants have since been updated to include a SKU, so you won’t be able to reproduce on that store unfortunately.

Hey @DavidT - thanks for reaching out

I did some digging and tested the same products(query: "-sku:*") query using Admin GraphQL API version 2026-07 on my test store, but I wasn’t able to reproduce the empty result. My query returned matching products, and the nested variants included SKU values represented as both "" and null.

Could you confirm whether this is still occurring for you with a newly created product whose SKU remains unset? If it does, can you please share the raw request and response, and a fresh x-request-id? It would also help to check whether the query is modified or combined with any other filters before your app sends it.

Hope this helps!

Well the issue is it works for most products, but for those few I shared it wasn’t. I included the request IDs and everything hoping you could look into exactly why. But we’ve since fixed the issue for the store owner and they have set a SKU now on all variants, so you won’t be able to reproduce it there. I have no way of knowing when the issue will occur again or what factors cause it.

The query was fresh because I did a test of their store in the API and only ran the queries I shared in the original message.

Hey @DavidT - thanks for your patience while I dug into this further.

I’ve confirmed that products(query: "-sku:*") returns products where none of the variants has an SKU. It won’t return a product containing a mix of variants with and without SKUs, which explains the result for the product you shared.

productVariants(query: "-sku:*") is a separate issue. The sku:* and -sku:* forms aren’t currently being applied correctly to productVariants. In our testing they act as no-op filters, and we’re investigating that behaviour.

I reviewed the request IDs, but the available information didn’t establish why that request returned an empty result. Since the variants were later updated, we can’t reproduce the original state. Please let us know if you are able to reproduce this again in the future so that we can investigate.

The older prefix-search report is related to the same filter area but is a different issue. Prefix searches such as sku:TST-DEL* are supported now and should return the expected results: productVariants - GraphQL Admin

For now, if you need products having at least one variant without an SKU, the fallback is to paginate through productVariants, request each variant’s sku and product, then filter null or blank values in your app. This requires reading the catalog client-side, so there’s a cost for larger catalogues and I recognize that this isn’t ideal.

The public documentation doesn’t currently explain the sku:* and -sku:* limitation or the mixed-variant behaviour described above. I’m also looking into clarifying this in the documentation.

I’ll follow up in thread once I have more information to share. I hope this helps in the meantime!

Thanks, that is indeed the scenario that was present. I would like to see documentation of this limitation as well as knowing if this applies to other text fields as well or just SKUs.

I guess what is confusing is if sku:* returns products where any variant has a SKU, then I expect the negation to do the exact opposite. But instead it returns products where all variants have no SKU, rather than if only some have no sku.

The logical negation of NOT ANY (none) should be SOME (at least 1), not ALL.

Thanks for the response here @DavidT. I see where you’re coming from as well. I’m doing some more digging here and looking into more clear documentation as well. I’ll follow up when I have more to share.