{"record":{"id":"48906c35370388c4","repo":"denoland/deno","slug":"err-out-of-range-48906c","errorCode":"ERR_OUT_OF_RANGE","errorMessage":"The value of \"historySize\" is out of range. It must be >= 0. Received ${historySize}","messagePattern":"The value of \"historySize\" is out of range\\. It must be >= 0\\. Received (.+?)","errorType":"validation","errorClass":"ERR_OUT_OF_RANGE","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/internal/readline/interface.mjs","lineNumber":243,"sourceCode":"    throw new ERR_INVALID_ARG_VALUE(\"completer\", completer);\n  }\n\n  if (history === undefined) {\n    history = [];\n  } else {\n    validateArray(history, \"history\");\n  }\n\n  if (historySize === undefined) {\n    historySize = kHistorySize;\n  }\n\n  if (typeof historySize !== \"number\") {\n    throw new ERR_INVALID_ARG_TYPE(\"historySize\", \"number\", historySize);\n  }\n\n  if (NumberIsNaN(historySize) || historySize < 0) {\n    throw new ERR_OUT_OF_RANGE(\"historySize\", \">= 0\", historySize);\n  }\n\n  // Backwards compat; check the isTTY prop of the output stream\n  //  when `terminal` was not specified\n  if (terminal === undefined && !(output === null || output === undefined)) {\n    terminal = !!output.isTTY;\n  }\n\n  const self = this;\n\n  this.line = \"\";\n  this[kSubstringSearch] = null;\n  this.output = output;\n  this.input = input;\n  this.history = history;\n  this.historySize = historySize;\n  this.removeHistoryDuplicates = !!removeHistoryDuplicates;\n  this.crlfDelay = crlfDelay","sourceCodeStart":225,"sourceCodeEnd":261,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/internal/readline/interface.mjs#L225-L261","documentation":"After the type check, historySize must be a non-negative, non-NaN number; NaN or any value < 0 throws ERR_OUT_OF_RANGE('historySize', '>= 0'). Zero is legal (disables history). This guards the ring buffer that stores previous input lines.","triggerScenarios":"createInterface({ historySize: -1 }); historySize: NaN from Number('unlimited') or parseInt failures that still produce NaN (a number type); arithmetic like size - offset going negative.","commonSituations":"Computing history size from a subtraction or percentage that can go below zero; Number(...) of a non-numeric env value producing NaN; sentinel values like -1 meaning 'unlimited' being forwarded directly.","solutions":["Treat 'unlimited' as a large finite number or omit the option, never -1","Clamp: Math.max(0, Number(cfg.historySize) || 0)","Check Number.isFinite before passing"],"exampleFix":"// before\ncreateInterface({ input, output, historySize: cfg.unlimited ? -1 : 30 });\n\n// after\ncreateInterface({ input, output, historySize: cfg.unlimited ? 10000 : 30 });","handlingStrategy":"validation","validationCode":"const historySize = Math.max(0, Number(cfg.historySize) || 30);\nreadline.createInterface({ input, output, historySize });","typeGuard":"const isNonNegativeHistorySize = (v: unknown): v is number =>\n  typeof v === 'number' && Number.isFinite(v) && v >= 0;","tryCatchPattern":"try {\n  rl = readline.createInterface({ input, historySize: size });\n} catch (err) {\n  if (err?.code === 'ERR_OUT_OF_RANGE' && /historySize/.test(err.message)) {\n    rl = readline.createInterface({ input, historySize: 0 });\n  } else throw err;\n}","preventionTips":["Never use -1 or NaN sentinels for history size; 0 disables history","Clamp computed sizes with Math.max(0, ...)"],"tags":["readline","node-compat","deno","range-error","history"],"backgroundTag":"argument-out-of-range","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-26T04:18:47.238Z"}