{"record":{"id":"b46845a8f9fe5a2b","repo":"nodejs/node","slug":"sqlitecachestore-options-maxcount-must-be-a-non-ne","errorCode":null,"errorMessage":"SqliteCacheStore options.maxCount must be a non-negative integer","messagePattern":"SqliteCacheStore options\\.maxCount must be a non-negative integer","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"deps/undici/src/lib/cache/sqlite-cache-store.js","lineNumber":106,"sourceCode":"          opts.maxEntrySize < 0\n        ) {\n          throw new TypeError('SqliteCacheStore options.maxEntrySize must be a non-negative integer')\n        }\n\n        if (opts.maxEntrySize > MAX_ENTRY_SIZE) {\n          throw new TypeError('SqliteCacheStore options.maxEntrySize must be less than 2gb')\n        }\n\n        this.#maxEntrySize = opts.maxEntrySize\n      }\n\n      if (opts.maxCount !== undefined) {\n        if (\n          typeof opts.maxCount !== 'number' ||\n          !Number.isInteger(opts.maxCount) ||\n          opts.maxCount < 0\n        ) {\n          throw new TypeError('SqliteCacheStore options.maxCount must be a non-negative integer')\n        }\n        this.#maxCount = opts.maxCount\n      }\n    }\n\n    if (!DatabaseSync) {\n      DatabaseSync = require('node:sqlite').DatabaseSync\n    }\n    this.#db = new DatabaseSync(opts?.location ?? ':memory:')\n\n    this.#db.exec(`\n      PRAGMA journal_mode = WAL;\n      PRAGMA synchronous = NORMAL;\n      PRAGMA temp_store = memory;\n      PRAGMA optimize;\n\n      CREATE TABLE IF NOT EXISTS cacheInterceptorV${VERSION} (\n        -- Data specific to us","sourceCodeStart":88,"sourceCodeEnd":124,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/undici/src/lib/cache/sqlite-cache-store.js#L88-L124","documentation":"Thrown when opts.maxCount is defined but is not a non-negative integer. maxCount caps how many cached responses (across all URLs) the store keeps; the constructor validates it the same way as maxEntrySize — must be a number, integral, and >= 0.","triggerScenarios":"Passing maxCount as a string ('100'), a float (1.5), a negative number, NaN, or Infinity. Also when a config layer returns undefined-as-string or a BigInt.","commonSituations":"Pulling maxCount from an env var without parseInt; using Number.MAX_SAFE_INTEGER as a stand-in for unlimited (that actually works but is a code smell); mixing up maxCount with maxEntrySize.","solutions":["Pass an integer: new SqliteCacheStore({ maxCount: 1000 }).","Coerce from config: Number.parseInt(process.env.CACHE_MAX_COUNT, 10).","Omit maxCount to keep the default cap.","Validate the value is finite and integral before passing."],"exampleFix":"// before\nnew SqliteCacheStore({ maxCount: process.env.CACHE_MAX_COUNT })\n// after\nnew SqliteCacheStore({ maxCount: Number.parseInt(process.env.CACHE_MAX_COUNT, 10) })","handlingStrategy":"validation","validationCode":"function coerceMaxCount(v) {\n  const n = Number(v)\n  if (!Number.isInteger(n) || n < 0) {\n    throw new TypeError('maxCount must be a non-negative integer')\n  }\n  return n\n}","typeGuard":"function isValidMaxCount(v) {\n  return typeof v === 'number' && Number.isInteger(v) && v >= 0\n}","tryCatchPattern":null,"preventionTips":["Parse env vars with Number.parseInt(..., 10).","Omit the option to keep the default cap.","Validate the parsed value before constructing the store.","Unit-test with string, float, and negative inputs."],"tags":["cache","sqlite","validation","numeric","undici"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}