{"record":{"id":"13bb9bc26cd5c942","repo":"nodejs/node","slug":"invalid-maxitems-must-be-a-positive-number-and-gr","errorCode":null,"errorMessage":"Invalid maxItems. Must be a positive number and greater than zero","messagePattern":"Invalid maxItems\\. Must be a positive number and greater than zero","errorType":"exception","errorClass":"InvalidArgumentError","httpStatus":null,"severity":"error","filePath":"deps/undici/src/lib/interceptor/dns.js","lineNumber":471,"sourceCode":"        break\n    }\n  }\n}\n\nmodule.exports = interceptorOpts => {\n  if (\n    interceptorOpts?.maxTTL != null &&\n    (typeof interceptorOpts?.maxTTL !== 'number' || interceptorOpts?.maxTTL < 0)\n  ) {\n    throw new InvalidArgumentError('Invalid maxTTL. Must be a positive number')\n  }\n\n  if (\n    interceptorOpts?.maxItems != null &&\n    (typeof interceptorOpts?.maxItems !== 'number' ||\n      interceptorOpts?.maxItems < 1)\n  ) {\n    throw new InvalidArgumentError(\n      'Invalid maxItems. Must be a positive number and greater than zero'\n    )\n  }\n\n  if (\n    interceptorOpts?.affinity != null &&\n    interceptorOpts?.affinity !== 4 &&\n    interceptorOpts?.affinity !== 6\n  ) {\n    throw new InvalidArgumentError('Invalid affinity. Must be either 4 or 6')\n  }\n\n  if (\n    interceptorOpts?.dualStack != null &&\n    typeof interceptorOpts?.dualStack !== 'boolean'\n  ) {\n    throw new InvalidArgumentError('Invalid dualStack. Must be a boolean')\n  }","sourceCodeStart":453,"sourceCodeEnd":489,"githubUrl":"https://github.com/nodejs/node/blob/1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e/deps/undici/src/lib/interceptor/dns.js#L453-L489","documentation":"Thrown by the DNS interceptor factory (`InvalidArgumentError`, code `UND_ERR_INVALID_ARG`) when `maxItems` is provided and is either not a number or is less than 1. `maxItems` bounds the size of the in-process DNS cache so it cannot grow unbounded over a long-running process; at least one slot is required. Unlike `maxTTL`, zero is explicitly rejected here (`< 1`).","triggerScenarios":"Passing `maxItems: 0`, a negative number, a non-number, or a fractional value intending a cap. The check is `typeof !== 'number' || < 1`. Floats ≥1 technically pass (the cache keying tolerates them) but an integer is intended.","commonSituations":"Setting `maxItems: 0` to 'disable' the cache (it errors, not disables); reading the value from config as a string; passing a value tuned for a different cache library that allowed zero.","solutions":["Pass a positive integer ≥1, e.g. `maxItems: 100`.","To effectively disable caching, set `maxTTL: 0` instead of shrinking `maxItems` to 0.","Coerce and validate env-derived values: `Number.isInteger(v) && v >= 1`."],"exampleFix":"// before\ndns({ maxItems: 0 })\ndns({ maxItems: process.env.DNS_MAX })\n\n// after\ndns({ maxItems: 100 })\ndns({ maxItems: Number(process.env.DNS_MAX) })","handlingStrategy":"validation","validationCode":"function validateMaxItems(v) {\n  if (v == null) return undefined\n  if (typeof v !== 'number' || v < 1 || !Number.isInteger(v)) {\n    throw new Error('maxItems must be a positive integer')\n  }\n  return v\n}","typeGuard":"function isPositiveInteger(v) {\n  return typeof v === 'number' && Number.isInteger(v) && v >= 1\n}","tryCatchPattern":null,"preventionTips":["Use maxTTL: 0 to disable expiry, not maxItems: 0.","Pass an integer ≥1 for the cache slot count."],"tags":["undici","interceptor","dns","cache","validation","config"],"backgroundTag":null,"analyzedSha":"1b2de5e052fc0fb95fd7fb6846dcec4ade598e9e","analyzedAt":"2026-08-13T00:53:24.642Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}