Skip to content

fix(search): tag autocomplete caches with LISTINGS_TAG#34

Merged
abdout merged 1 commit into
mainfrom
fix/autocomplete-cache-tags
May 10, 2026
Merged

fix(search): tag autocomplete caches with LISTINGS_TAG#34
abdout merged 1 commit into
mainfrom
fix/autocomplete-cache-tags

Conversation

@abdout
Copy link
Copy Markdown
Contributor

@abdout abdout commented May 10, 2026

Hardening — surfaced by today's deploy run.

Why

getLocationSuggestions and getPopularLocations were unstable_cache-wrapped with a 1h TTL but no tags. That meant the only way an entry got refreshed was the TTL — revalidateTag() and updateTag() were no-ops against them.

Today's deploy hit this concretely:

  1. The trigram-aware code shipped before its pg_trgm migration ran.
  2. The catch block returned [] for every fuzzy query for ~30 minutes.
  3. Those empty arrays got cached under their (query, limit) keys.
  4. The migration was applied; direct DB verified the operator now returns matches.
  5. The API still returned [] for the original cached queries until the TTL elapsed — every q=khartom request kept serving the broken result.

I confirmed the diagnosis live: q=Khartom (capital K, never cached) returned the correct 3-city match, while q=khartom (lowercased, originally cached empty) still returned [].

Fix

Both autocomplete unstable_cache calls now declare tags: [LISTINGS_TAG]. The mutations in listing-actions.ts (create/update/publish/unpublish/delete) already call updateTag("listings") to invalidate the listings page cache — those same calls now also bust autocomplete. A deploy that fixes a query path takes effect within the next mutation rather than waiting an hour.

Validation

pnpm typecheck ✅ exit 0
pnpm vitest run tests/actions/search-actions.test.ts ✅ 19 / 19

🤖 Generated with Claude Code

getLocationSuggestions and getPopularLocations were cached for 1h
without any tags. That meant any stale entry — including the
empty-array result returned by the catch block when pg_trgm wasn't
yet installed — survived for the full TTL even after a fix was
deployed.

Concrete production receipt:
  1. PR #26 deployed trigram code that needs pg_trgm
  2. Migration didn't apply (P3005), operator threw, catch returned []
  3. unstable_cache stored {q:'khartom', limit:10}: []
  4. Migration was applied manually 30 min later
  5. Direct DB: 'khartom' % 'Khartoum' returns true ✓
  6. But /api/search/locations?q=khartom still returned [] for ~1h
     because the cache key was bound to the broken result

Fixing forward: tag both autocomplete caches with LISTINGS_TAG —
the same tag listing mutations already call updateTag() against.
Now create/update/publish/unpublish/delete invalidate autocomplete
in addition to /listings, and a deploy that fixes a query path
takes effect within the next mutation rather than waiting an hour.

Verified locally:
  pnpm typecheck → exit 0
  pnpm vitest run tests/actions/search-actions.test.ts → 19/19

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 10, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
mkan Ready Ready Preview, Comment May 10, 2026 0:24am

@abdout abdout merged commit 24ba6ac into main May 10, 2026
8 checks passed
@abdout abdout deleted the fix/autocomplete-cache-tags branch May 10, 2026 12:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant