[Bug]: Stale cache served for list responses with caching feature flag enabled
#14903 opened on Mar 17, 2026
Description
Package.json file
"dependencies": {
"@asteasolutions/zod-to-openapi": "^7.3.4",
"@aws-sdk/client-s3": "^3.992.0",
"@aws-sdk/client-sesv2": "^3.992.0",
"@aws-sdk/credential-providers": "^3.992.0",
"@grpc/grpc-js": "^1.14.0",
"@medusajs/admin-sdk": "2.13.1",
"@medusajs/cli": "2.13.1",
"@medusajs/event-bus-redis": "^2.13.1",
"@medusajs/framework": "2.13.1",
"@medusajs/medusa": "2.13.1",
"@medusajs/workflows-sdk": "^2.13.1",
"@opensearch-project/opensearch": "^3.5.1",
"@types/sharp": "^0.31.1",
"axios": "^1.13.5",
"date-fns": "^4.1.0",
"dd-trace": "^5.81.0",
"grpc-web": "^1.5.0",
"jsonwebtoken": "9.0.3",
"jwks-rsa": "^3.2.0",
"kafkajs": "^2.2.4",
"lodash.merge": "^4.6.2",
"openai": "^6.16.0",
"papaparse": "^5.5.3",
"react-easy-crop": "^5.5.6",
"sharp": "^0.34.5",
"swagger-ui-express": "^5.0.1",
"winston": "^3.18.3",
"zod": "^3.25.76"
},
"devDependencies": {
"@medusajs/test-utils": "2.13.1",
"@swc/core": "^1.7.28",
"@swc/jest": "^0.2.36",
"@types/jest": "^29.5.13",
"@types/kafkajs": "^1.8.2",
"@types/lodash.merge": "^4.6.9",
"@types/multer": "^2.0.0",
"@types/node": "^20.0.0",
"@types/react": "^18.3.2",
"@types/react-dom": "^18.2.25",
"@types/supertest": "^6.0.3",
"@types/swagger-ui-express": "^4.1.8",
"@types/winston": "^2.4.4",
"cross-env": "^7.0.3",
"husky": "^9.1.7",
"jest": "^29.7.0",
"prettier": "^3.5.3",
"prop-types": "^15.8.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"supertest": "^7.1.1",
"ts-node": "^10.9.2",
"typescript": "^5.6.2",
"vite": "^5.2.11",
"yalc": "^1.0.0-pre.53"
},
Node.js version
v22
Database and its version
irrelevant, but v18.3
Operating system name and version
Every
Browser name
No response
What happended?
Hello All,
When enabling featureFlags: { caching: true }, list endpoints, i.e. /store/products return stale data after entity updates that affect filter-relevant fields.
Steps to reproduce:
Enable caching in medusa-config:
featureFlags: {
caching: true,
}
Create a product in draft status
Hit GET /store/products (response gets cached, draft product is excluded by status filter)
Publish the product via the admin API
Hit GET /store/products again
Expected: The newly published product appears in the response.
Actual: The cached response from step 3 is returned. The published product is missing until the cache TTL expires.
Expected behavior
The list cache gets properly invalidated.
Actual behavior
Possible root cause:
buildAffectedCacheKeys in packages/modules/caching/src/utils/parser.ts only generates Entity:list:* invalidation tags for created and deleted operations:
if (entity.isInArray || ["created", "deleted"].includes(operation)) {
keys.add( ${entity.type}:list:* )
}
When a product.updated event fires, the invalidation only produces Product:prod_xyz as a tag. Since the product wasn't part of any cached list response (it was filtered out while in draft), no cached entry has that tag associated with it. The list wildcard tag that would actually clear the stale response is never generated.
This isn't limited to products - it affects every entity type where cached list queries use filters. Any update that changes whether an entity matches a given filter (status changes, category reassignment, sales channel changes, etc.) will result in stale list responses.
Suggested fix:
Always include the list wildcard tag regardless of operation type:
keys.add( ${entity.type}:list:* )
The cache layer has no way to know which fields are filter-relevant, so the safe default should probably be to invalidate list caches on any mutation. Individual entity caches (Product:prod_123) would still be preserved for updates that only affect a single entity lookup. I'm not familiar with Medusa source code though, so there might be better ways, I think.
Link to reproduction repo
can be reproduced in likely every single medusa instance with caching enabled