Storefront API `search` query: keyword stops filtering when combined with a field filter (e.g. `tag:`), so unrelated products are returned

Summary

In the Storefront API search query, a free-text keyword filters correctly when used alone. But as soon as a field filter (tag:,
NOT tag:, vendor: …) is combined with it, the keyword no longer narrows the results. The field filter is applied correctly,
and the keyword only affects ranking. As a result, every product that passes the field filter is returned.

No errors are returned. We have not changed our code around this, and the behavior is the same on every API version we tried.

(The keyword and tag names below are placeholders. Counts and request IDs are real.)

Reproduction

{
  search(query: "KEYWORD AND NOT tag:tag-a", first: 5, types: [PRODUCT]) {
    totalCount
    nodes { ... on Product { title } }
  }
}

Store facts:

  • 2 products have KEYWORD in the title. Both have tag-b. Neither has tag-a, tag-c or tag-d.
  • The store has 470 searchable products in total.

Results

# Query Field Expected Actual x-request-id
1 KEYWORD search 2 2 –
2 tag:tag-a search 45 45 e9345d64-64c9-48f6-b667-c24910c1a1b7-1790905047
3 KEYWORD AND tag:tag-a search 0 45 (same set as #2; the keyword products are not included)
a1166f21-0097-48bc-86c9-e339bb851d86-1790905046
4 NOT tag:tag-a search 425 425 103dcc2f-3fae-4f08-9ed4-56230ef8b241-1790905047
5 KEYWORD AND NOT tag:tag-a search 2 425 (the 2 keyword products ranked first, then unrelated products)
18feb4f0-e04c-44d2-b934-bd07d34d33a3-1790905044
6 KEYWORD AND NOT tag:tag-b search 0 367 (the keyword products are correctly excluded; everything else without
tag-b is returned) dd60e0fc-16b5-4c2b-90cd-98c17a55007c-1790905045
7 KEYWORD AND NOT vendor:foo search 2 470 (whole catalog) 1bf0b2d7-7a53-4c7b-897a-9fb3a4fd2463-1790905048
8 KEYWORD AND NOT tag:tag-c AND NOT tag:tag-d products 2 2 –
  • The field filter itself works (#2, #4, #6). It is the keyword that stops filtering (#3, #5, #6, #7).
  • Omitting AND, using -tag: instead of NOT tag:, wrapping the filters in parentheses, and prefix: NONE all give the same
    result.
  • Same result on API versions 2024-10, 2025-07 and 2026-01.
  • It happens with both ASCII and non-ASCII (Japanese) tag names.
  • The same kind of query on products(query:) works as expected (#8).

Expected behavior

According to the search syntax documentation, the same syntax applies across
the platform including the Storefront API, and AND is implied between terms. The only caveat stated for the Storefront search
query is that terms without a field name match only product titles and descriptions.

So we expect KEYWORD AND <field filter> to return only products that match the keyword and pass the field filter.

Possibly related

Shopify search and discovery bug (July 2026) reports
unrelated products appearing below the correct match, and the reply from the Search team there describes it as semantic search
broadening results beyond exact matches. The ranking pattern looks the same here. The difference is that in our case the keyword
alone still returns only the 2 exact matches (#1); the broadening only happens when a field filter is added.

Questions

  1. Is this intended behavior of the search query (e.g. semantic search), or a bug?
  2. If it is intended, what is the supported way to combine a keyword with tag exclusion in search? (productFilters only seems
    to support positive tag matching.)
  3. Is there a way to opt out of the broadened matching per request or per shop?

Environment

  • API: Storefront API (GraphQL), version 2026-01. Same result on 2024-10 and 2025-07.
  • Target: search query (products query used for comparison)
  • Errors: none. The response is HTTP 200 with no errors field; only the result set is wrong.
  • Client: Hydrogen 2025.7 (Oxygen)
  • First noticed: late September 2026. We don’t know exactly when it started.

This matches the semantic broadening behavior the Search team described in that other thread, the keyword essentially gets treated as a ranking signal rather than a hard filter once a field term is present. Since your #8 shows products(query:) with the same syntax filters correctly, I’d use that as the workaround for now rather than waiting on search to be fixed.

Thanks for the reply.
I’ll try looking for that thread.

However, I want to exclude items that have a certain tag.

If I search first and then exclude them, the number of products displayed per page gets messed up, you see.

To be clear, run the whole query against products(query:) instead of search, not search-then-filter client side. Since products applies the tag exclusion server side like your #8 already showed, totalCount and pagination come back correct without any manual filtering after the fact.