denoland/deno · error · RangeError
incomingHighWaterMark cannot be negative
Error message
incomingHighWaterMark cannot be negative
What it means
WebTransportDatagramDuplexStream.incomingHighWaterMark controls backpressure for the readable side of datagram reception. Deno's setter in ext/web/webtransport.js accepts an 'unrestricted double' and throws a RangeError for negative numbers or NaN. Values below 1 (including 0 and fractions) are not errors — they are clamped up to 1.
Source
Thrown at ext/web/webtransport.js:839
throw new RangeError("outgoingMaxAge cannot be negative");
}
if (value === 0) value = null;
this.#outgoingMaxAge = value;
}
get incomingHighWaterMark() {
webidl.assertBranded(this, WebTransportDatagramDuplexStreamPrototype);
return this.#incomingHighWaterMark;
}
set incomingHighWaterMark(value) {
webidl.assertBranded(this, WebTransportDatagramDuplexStreamPrototype);
value = webidl.converters["unrestricted double"](
value,
"Failed to execute 'incomingHighWaterMark' on 'WebTransportDatagramDuplexStream'",
);
if (value < 0 || NumberIsNaN(value)) {
throw new RangeError("incomingHighWaterMark cannot be negative");
}
if (value < 1) value = 1;
this.#incomingHighWaterMark = value;
}
get outgoingHighWaterMark() {
webidl.assertBranded(this, WebTransportDatagramDuplexStreamPrototype);
return this.#outgoingHighWaterMark;
}
set outgoingHighWaterMark(value) {
webidl.assertBranded(this, WebTransportDatagramDuplexStreamPrototype);
value = webidl.converters["unrestricted double"](
value,
"Failed to execute 'outgoingHighWaterMark' on 'WebTransportDatagramDuplexStream'",
);
if (value < 0 || NumberIsNaN(value)) {
throw new RangeError("outgoingHighWaterMark cannot be negative");View on GitHub (pinned to 9ad36f7a2c)
Solutions
- Assign a positive finite number (bytes/entries as the API defines).
- Convert 'unset' sentinels to a sane default like 1 instead of -1.
- Validate with Number.isFinite(v) && v >= 0 before assigning.
- Note the clamp: anything in [0, 1) becomes 1, so small values are safe.
Example fix
// before duplex.incomingHighWaterMark = cfg.hwm ?? -1; // after duplex.incomingHighWaterMark = cfg.hwm ?? 1;
Defensive patterns
Strategy: validation
Validate before calling
function toHighWaterMark(v, fallback = 1) {
return Number.isFinite(v) && v >= 1 ? v : fallback;
}
duplex.incomingHighWaterMark = toHighWaterMark(cfg.hwm); Type guard
function isValidHighWaterMark(v) {
return typeof v === "number" && Number.isFinite(v) && v >= 0;
} Try / catch
try { duplex.incomingHighWaterMark = v; } catch (e) { if (e instanceof RangeError) duplex.incomingHighWaterMark = 1; else throw e; } Prevention
- Default buffer sizes to a positive constant, never to -1.
- Note values under 1 are clamped to 1 — pick realistic buffer sizes.
- Validate numeric tuning knobs once at config load.
When it happens
Trigger: duplex.incomingHighWaterMark = -5; NaN from an uninitialized variable; configuration piping a '-1 = default' sentinel straight into the setter.
Common situations: Size/buffer tuning exposed in config files; unit conversions that yield negative numbers when inputs are swapped; NaN defaults from destructuring with misspelled keys.
Related errors
- outgoingHighWaterMark cannot be negative
- incomingMaxAge cannot be negative
- outgoingMaxAge cannot be negative
- ERR_INVALID_ARG_VALUE
- BenchContext::start() has already been invoked
AI-assisted analysis of denoland/deno@9ad36f7a2c (2026-08-20).
Data as JSON: /api/errors/4cd107e22f1616ad.
Report an issue: GitHub.