denoland/deno · error · ERR_OUT_OF_RANGE
ERR_OUT_OF_RANGE
ERR_OUT_OF_RANGE
Error message
The value of "historySize" is out of range. It must be >= 0. Received ${historySize} What it means
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.
Source
Thrown at ext/node/polyfills/internal/readline/interface.mjs:243
throw new ERR_INVALID_ARG_VALUE("completer", completer);
}
if (history === undefined) {
history = [];
} else {
validateArray(history, "history");
}
if (historySize === undefined) {
historySize = kHistorySize;
}
if (typeof historySize !== "number") {
throw new ERR_INVALID_ARG_TYPE("historySize", "number", historySize);
}
if (NumberIsNaN(historySize) || historySize < 0) {
throw new ERR_OUT_OF_RANGE("historySize", ">= 0", historySize);
}
// Backwards compat; check the isTTY prop of the output stream
// when `terminal` was not specified
if (terminal === undefined && !(output === null || output === undefined)) {
terminal = !!output.isTTY;
}
const self = this;
this.line = "";
this[kSubstringSearch] = null;
this.output = output;
this.input = input;
this.history = history;
this.historySize = historySize;
this.removeHistoryDuplicates = !!removeHistoryDuplicates;
this.crlfDelay = crlfDelayView on GitHub (pinned to 9ad36f7a2c)
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
Example fix
// before
createInterface({ input, output, historySize: cfg.unlimited ? -1 : 30 });
// after
createInterface({ input, output, historySize: cfg.unlimited ? 10000 : 30 }); Defensive patterns
Strategy: validation
Validate before calling
const historySize = Math.max(0, Number(cfg.historySize) || 30);
readline.createInterface({ input, output, historySize }); Type guard
const isNonNegativeHistorySize = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v) && v >= 0;
Try / catch
try {
rl = readline.createInterface({ input, historySize: size });
} catch (err) {
if (err?.code === 'ERR_OUT_OF_RANGE' && /historySize/.test(err.message)) {
rl = readline.createInterface({ input, historySize: 0 });
} else throw err;
} Prevention
- Never use -1 or NaN sentinels for history size; 0 disables history
- Clamp computed sizes with Math.max(0, ...)
When it happens
Trigger: createInterface({ historySize: -1 }); historySize: NaN from Number('unlimited') or parseInt failures that still produce NaN (a number type); arithmetic like size - offset going negative.
Common situations: 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.
Related errors
- ERR_INVALID_ARG_TYPE
- ERR_INVALID_ARG_VALUE
- ERR_INVALID_CURSOR_POS
- ERR_INVALID_ARG_VALUE
- ERR_USE_AFTER_CLOSE
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/48906c35370388c4.
Report an issue: GitHub.