evalScript caches script SHAs in a WeakMap per Redis client and never invalidates them. Redis's script cache is in-memory only (not persisted by RDB/AOF, not replicated under effects-replication), so any Redis restart, failover, or SCRIPT FLUSH leaves every cached SHA stale. Subsequent evalsha calls throw NOSCRIPT until the Node process is restarted.
Repro
- Enqueue a job (loads scripts)
redis-cli SCRIPT FLUSH
- Enqueue another →
NOSCRIPT No matching script, never recovers
Impact
Hit this in prod on self-hosted OpenPanel: GKE rescheduled the Redis pod, /track served 500s for hours while /healthcheck (PING-only) stayed green. Only fix was manual kubectl rollout restart.
Fix
Catch NOSCRIPT in evalScript, drop the cached SHA, reload, retry once. Same pattern ioredis/BullMQ use. Happy to PR.
evalScriptcaches script SHAs in aWeakMapper Redis client and never invalidates them. Redis's script cache is in-memory only (not persisted by RDB/AOF, not replicated under effects-replication), so any Redis restart, failover, orSCRIPT FLUSHleaves every cached SHA stale. Subsequentevalshacalls throwNOSCRIPTuntil the Node process is restarted.Repro
redis-cli SCRIPT FLUSHNOSCRIPT No matching script, never recoversImpact
Hit this in prod on self-hosted OpenPanel: GKE rescheduled the Redis pod,
/trackserved 500s for hours while/healthcheck(PING-only) stayed green. Only fix was manualkubectl rollout restart.Fix
Catch
NOSCRIPTinevalScript, drop the cached SHA, reload, retry once. Same pattern ioredis/BullMQ use. Happy to PR.