denoland/deno · error · ERR_INVALID_ARG_VALUE
ERR_INVALID_ARG_VALUE
ERR_INVALID_ARG_VALUE
Error message
The property 'input.escapeCodeTimeout' is invalid. Received ${this.escapeCodeTimeout} What it means
readline.createInterface requires options.escapeCodeTimeout to be a finite number when provided (it is the ms delay waiting for an escape-sequence, default 500). Number.isFinite(input.escapeCodeTimeout) failing — NaN, Infinity, or any non-number including strings — throws ERR_INVALID_ARG_VALUE('input.escapeCodeTimeout'). Note the Deno polyfill reports this.escapeCodeTimeout (still the default 500 at that point) in the message, so 'Received 500' does not reflect the value you actually passed.
Solutions
- Pass a plain finite number: escapeCodeTimeout: 1000
- Coerce from config: Number(cfg.escapeCodeTimeout) and check Number.isFinite before passing
- Omit the option entirely to keep the 500 ms default
Example fix
// before
createInterface({ input, escapeCodeTimeout: Number.POSITIVE_INFINITY });
// after
createInterface({ input, escapeCodeTimeout: 1000 }); Defensive patterns
Strategy: validation
Validate before calling
function makeRl(input: NodeJS.ReadableStream, opts: Record<string, unknown>) {
const t = opts.escapeCodeTimeout;
return readline.createInterface({
input,
...(Number.isFinite(t) ? { escapeCodeTimeout: t as number } : {}),
});
} Type guard
const isFiniteNumber = (v: unknown): v is number => typeof v === 'number' && Number.isFinite(v);
Try / catch
try {
rl = readline.createInterface({ input, escapeCodeTimeout: t } as readline.ReadLineOptions);
} catch (err) {
if (err?.code === 'ERR_INVALID_ARG_VALUE' && /escapeCodeTimeout/.test(err.message)) {
rl = readline.createInterface({ input }); // default 500ms
} else throw err;
} Prevention
- Coerce config/env timeouts with Number() and verify Number.isFinite before passing
- Omit escapeCodeTimeout unless you specifically tune escape-sequence timing
When it happens
Trigger: createInterface({ input, escapeCodeTimeout: Infinity }); passing '500' as a string from config; computing the value as a division that yields NaN or Infinity.
Common situations: Tuning escape-code timing for slow SSH/telnet terminals; values read from env vars or JSON config that arrive as strings; reusing a timeout constant that was set to Infinity elsewhere.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
- Timeouts: ETIMEDOUT, deadlines, and hung requests — what actually expires when a request times out.
Related errors
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/158b9aa63a2ee51e.
Report an issue: GitHub.
Appendix: source
Thrown at ext/node/polyfills/internal/readline/interface.mjs:209
output = input.output;
completer = input.completer;
terminal = input.terminal;
history = input.history;
historySize = input.historySize;
signal = input.signal;
if (input.tabSize !== undefined) {
validateUint32(input.tabSize, "tabSize", true);
this.tabSize = input.tabSize;
}
removeHistoryDuplicates = input.removeHistoryDuplicates;
if (input.prompt !== undefined) {
prompt = input.prompt;
}
if (input.escapeCodeTimeout !== undefined) {
if (NumberIsFinite(input.escapeCodeTimeout)) {
this.escapeCodeTimeout = input.escapeCodeTimeout;
} else {
throw new ERR_INVALID_ARG_VALUE(
"input.escapeCodeTimeout",
this.escapeCodeTimeout,
);
}
}
if (signal) {
validateAbortSignal(signal, "options.signal");
}
crlfDelay = input.crlfDelay;
input = input.input;
}
if (completer !== undefined && typeof completer !== "function") {
throw new ERR_INVALID_ARG_VALUE("completer", completer);
}
View on GitHub (pinned to 9ad36f7a2c)