[ Bug report ] is_price_reduced:false query filter returning products with reduced prices

The is_price_reduced:false query filter is not working correctly. It’s returning products that clearly have reduced prices (where compareAtPrice exists and is greater than price).

API Details

  • API Version Tested: 2025-10, 2025-07, 2025-04 (bug persists across versions)

  • Endpoint: GraphQL Admin API

query ($cursor: String) {
  products(
    first: 50
    after: $cursor
    query: "status:active AND is_price_reduced:false"
  ) {
    pageInfo {
      hasNextPage
      hasPreviousPage
    }
    edges {
      cursor
      node {
        id
        title
        vendor
        status
        variants(first: 1) {
          edges {
            node {
              id
              price
              compareAtPrice
              barcode
              inventoryQuantity
              inventoryPolicy
              inventoryItem {
                id
                unitCost {
                  amount
                }
              }
            }
          }
        }
      }
    }
  }
}


The query returns products like this:

{
  "id": "gid://shopify/ProductVariant/40550221217978",
  "price": "8.89",
  "compareAtPrice": "9.88",
  "barcode": "8058664070466",
  "inventoryQuantity": 0,
  "inventoryPolicy": "DENY"
}

Since compareAtPrice (9.88) is greater than price (8.89), this product IS price reduced and should NOT be returned when filtering by is_price_reduced:false.

Additional Context

  • The inverse (is_price_reduced:true) appears to work correctly and returns only discounted products

  • This was tested directly in the GraphiQL Admin API interface and confirmed as an API-level issue

  • I remember this exact same bug from about 2-3 years ago but was resolved by Shopify, yet it appears to have regressed

Anyone care to investigate? This bug makes it impossible to properly paginate through non-discounted products, as we cannot trust the filter to exclude discounted items. This has been working up until recently, so it has since broken one of the main features of our private app.

1 Like

Hey @Panos,

Can you confirm if any of the variants on that product don’t have a compare at price set? The reason I ask is this filter uses the CollectionRuleColumn.

The docs mention the following logic for this filter:

  • is_price_reduced:true (IS_SET) = Products with at least one variant with compareAtPrice set
  • is_price_reduced:false (IS_NOT_SET) = Products with at least one variant with compareAtPrice not set

This means a product with mixed variants (some with compareAtPrice, some without) will match both filters simultaneously.

For context, I created a test product with 4 variants - 3 with compareAtPrice set and 1 without. It correctly appeared in both :true and :false results, which matches the documented behavior.

Let me know if your results are still different here.

Hey @pvoulg, did the above help clarify this at all?

Hi @KyleG-Shopify, thanks for looking into this. I seem to have missed your response for some reason.

The store I’m testing the filter on actually only has 1 variant per product (the default one), so this case doesn’t apply here unfortunately.

I noticed that by setting the status filter to “draft”, or by removing the status filter altogether, it seems to return the products correctly. Only when using this specific query (“status:active AND is_price_reduced:false”) does it produce wrong results (ie. products with the compare_at_price field populated).

I managed to reproduce the error on one store (with both single and multiple variants), using GraphiQL, but did not manage to do so on another. So, I’m still kind of baffled.

Hey @pvoulg that was probably my fault as I didn’t tag your name properly :person_facepalming:

Thanks for those additional details. I was able to replicate this as well on my test store. I created a product on my store that should be price reduced: true, but it kept returning in the false filter. I had to toggle the status in the admin to draft for the filter to update. Toggling it back to active and it was then returning properly in true (and excluded from false).

I’m investigating this further and will update you here once I know more.

1 Like