Ultimate

X_CACHE_LIMIT_INVALID

Means

a tier is given a numeric limit outside the domain its option accepts, refused at construction. Three domains, and the refusal names which: a capacity (maxEntries, maxBytes) is a whole number greater than zero; a duration (defaultTtlMs, loadDeadlineMs, a driver's request budget) is a whole number of milliseconds greater than zero; a similarity floor is a number from 0 to 1. So finite zero, a negative, a fraction and an unsafe integer are all refused too — not only NaN and Infinity

Typical cause

maxEntries, maxBytes, defaultTtlMs, loadDeadlineMs or a similarity floor arriving as NaN or Infinity — most often Number(process.env.CACHE_LIMIT) on an unset variable, which is NaN and is not nullish, so ?? does not catch it and Math.max/Math.min propagate it. The failure is the dangerous direction: a comparison against NaN is false for every entry, so the limit stops being enforced rather than being enforced wrongly — an unbounded cache that reports healthy. The cause names that mechanism only for NaN: the same refusal also catches Infinity, 0, a fraction and an unsafe integer, where the bound is applied as given rather than disabled — a ceiling of Infinity is never exceeded and a similarity floor of Infinity is never met, which are opposite outcomes one sentence cannot claim at once. Raised at construction rather than on the first write, where X_CACHE_TTL_INVALID would have named the write instead of the config

Fix

the cause names the tier and the option; set it in app.config.ts, and parse an environment value before passing it. Where the value is a call argument rather than a config key — cacheStack({ loadDeadlineMs }), lookup(embedding, override) — the fix names the argument, because sending that caller to app.config.ts names a key that does not exist. bun run finite-bounds is the repo-wide rule

Listed under Cache

This page as markdown