#3042·typesense

filter_curated_hits is ignored for pinned documents that have no value for the group_by field

Author: thebossza101Created Sep 12, 2026Updated Sep 12, 2026

Description

When group_by is active, filter_curated_hits=true is not applied to a pinned document that has no value for the group_by field. The pinned document is returned even though it does not match filter_by.

A pinned document that does have a value for the group_by field is filtered out correctly under the exact same query, and both are filtered out correctly when group_by is removed — so the only variable is the presence of the grouping field on the pinned document.

This is easy to miss in production: filter_curated_hits is typically used to stop curated items that are out of stock / disabled / region-restricted from surfacing, and the leak is silent and affects only the subset of documents where the grouping field is absent.

Steps to reproduce

Against a Typesense v30.2 instance:

1. Create the collectiongroup_field is optional so some documents can omit it:

bash
curl -X POST 'http://localhost:8108/collections' \
  -H 'X-TYPESENSE-API-KEY: xyz' -H 'Content-Type: application/json' -d '{
  "name":"repro_fch_groupby",
  "fields":[
    {"name":"title","type":"string"},
    {"name":"brand","type":"string","facet":true},
    {"name":"group_field","type":"string","facet":true,"optional":true}
  ]}'

2. Import 4 documentsbeta-no-group is the only one without group_field:

bash
curl -X POST 'http://localhost:8108/collections/repro_fch_groupby/documents/import?action=create' \
  -H 'X-TYPESENSE-API-KEY: xyz' -H 'Content-Type: text/plain' --data-binary '
{"id":"alpha-1","title":"alpha one","brand":"alpha","group_field":"g1"}
{"id":"alpha-2","title":"alpha two","brand":"alpha","group_field":"g2"}
{"id":"beta-with-group","title":"beta with group","brand":"beta","group_field":"g3"}
{"id":"beta-no-group","title":"beta no group","brand":"beta"}'

3. Search with filter_by=brand:=alpha and pin a brand=beta document (so the pinned document never matches the filter), with filter_curated_hits=true:

bash
# A — pinned doc HAS group_field, group_by active  → correct
curl -G 'http://localhost:8108/collections/repro_fch_groupby/documents/search' \
  -H 'X-TYPESENSE-API-KEY: xyz' \
  --data-urlencode 'q=*' --data-urlencode 'query_by=title' \
  --data-urlencode 'filter_by=brand:=alpha' \
  --data-urlencode 'pinned_hits=beta-with-group:1' \
  --data-urlencode 'filter_curated_hits=true' \
  --data-urlencode 'group_by=group_field' --data-urlencode 'group_limit=1'

# B — pinned doc has NO group_field, group_by active → BUG
curl -G 'http://localhost:8108/collections/repro_fch_groupby/documents/search' \
  -H 'X-TYPESENSE-API-KEY: xyz' \
  --data-urlencode 'q=*' --data-urlencode 'query_by=title' \
  --data-urlencode 'filter_by=brand:=alpha' \
  --data-urlencode 'pinned_hits=beta-no-group:1' \
  --data-urlencode 'filter_curated_hits=true' \
  --data-urlencode 'group_by=group_field' --data-urlencode 'group_limit=1'

Results

# pinned document group_by returned ids found
A beta-with-group (has group_field) yes alpha-2, alpha-1 2 correct
B beta-no-group (no group_field) yes beta-no-group, alpha-2, alpha-1 3 bug
C beta-with-group no alpha-2, alpha-1 2 correct
D beta-no-group no alpha-2, alpha-1 2 correct

Adding group_missing_values=false to case B does not change the outcome — beta-no-group is still returned.

Expected behaviour

In case B, beta-no-group does not match filter_by=brand:=alpha, so with filter_curated_hits=true it should be excluded from the results — the same way it is in cases C and D, and the same way beta-with-group is in case A.

Actual behaviour

beta-no-group is returned at the top of the results and counted in found.

Environment

  • Typesense v30.2 (self-hosted, /debug{"state":1,"version":"30.2"})

Possibly related

  • #1416 — brought filter_curated_hits to pinned_hits (fixed in v27); that path works here whenever the pinned document has a grouping value.
  • #2033 — pinned_hits + group_by + filter_curated_hits, where the whole group was dropped if the pinned document did not match (fixed in 28.0.rc33). The behaviour reported here looks like the complementary case: a pinned document with no group at all appears to escape the curated-hit filtering entirely.