(Produced by Claude Fable)
### Problem/Motivation
The three Search API views cache plugins are inconsistent:
- SearchApiTagCache (search_api_tag) — uses SearchApiCachePluginTrait
- SearchApiTimeCache (search_api_time) — uses SearchApiCachePluginTrait
- SearchApiTimeTagCache (search_api_time_tag) — extends core Time directly and does NOT use the trait; it only overrides getRowCacheTags().
SearchApiCachePluginTrait::cacheSet() stores the full Search API ResultSet alongside the view rows, and cacheGet() restores it on a hit, explicitly "to trick Search API into believing a search happened, to make faceting et al. work". Because SearchApiTimeTagCache lacks the trait, it falls through to core CachePluginBase::cacheGet(), which restores only $view->result. The Search API query is never executed and never given its cached results, so SearchApiQuery::getSearchApiResults() returns an empty ResultSet for the rest of the request.
Anything that consumes result-level data after execution breaks on every results cache hit. The most visible victim is facets_exposed_filters (Facets 3.x): facets_exposed_filters_views_post_execute() reads getExtraData('search_api_facets'), finds nothing, and re-renders the exposed form with no facet widgets — the filters simply vanish from the page until the cache entry expires or is invalidated.
### Steps to reproduce
1. Search API view with facets exposed filters (Facets 3.x) working normally.
2. Set the view's caching to "Search API (time and tag-based)" with any lifespan.
3. Clear caches, load the page — facets render (cache miss, real query).
4. Reload the page — facets are gone (results cache hit, ResultSet not restored).
5. Load the same path with any extra query argument (results key varies by url.query_args) — facets render again, because that's a fresh cache miss.
Switching the same view to "Search API (tag-based)" or "Search API (time-based)" — the two plugins that use the trait — fixes it with no other changes, which isolates the missing trait as the cause.
Verified on search_api 8.x-1.41, facets 3.0.3, Drupal core 11.x, with both the database and Redis cache backends.
### Proposed resolution
Add `use SearchApiCachePluginTrait;` to SearchApiTimeTagCache, matching SearchApiTimeCache (which also extends core Time, so the trait is proven compatible with the time-based expiry handling: cacheSetMaxAge() is resolved via the trait's cacheSet()).
If there's a reason the trait was intentionally omitted, the plugin's help text should at minimum warn that it is incompatible with Facets and any other module that reads the Search API ResultSet after execution — currently it looks like a drop-in combination of the two working plugins.
### Workaround for anyone hitting this
Use "Search API (tag-based)" or "Search API (time-based)" caching instead of "Search API (time and tag-based)".
Related issues (facet-vanishing symptoms with non-Search-API cache plugins — same underlying pattern of results being restored without Search API data):
- #2779283: Cached Search API View Causes Facet Blocks to Vanish
- #2809171: Facet block vanishes after refresh if view uses caching
Issue fork search_api-3613515
Show commands
Start within a Git clone of the project using the version control instructions.
Or, if you do not have SSH keys set up on git.drupalcode.org:
Comments
Comment #4
sriram_s commentedConfirmed on 8.x-1.41. With "Search API (time and tag-based)", warm the results cache then clear only the render cache: facets render nothing while result rows still show. The cache entry stores three keys where the other plugins store four, so the ResultSet is never saved or restored.
MR !344 adds the trait, matching SearchApiTimeCache. Facets go 0 back to 3 in that state. Added testCachedResultSetIsRestored() across all three plugins; it fails on time_tag only. The existing testDisplayCacheability() passes with the bug present since it checks the cache is populated, not that the ResultSet survives.