{"record":{"id":"2fd9be34f39e5473","repo":"denoland/deno","slug":"outgoinghighwatermark-cannot-be-negative","errorCode":null,"errorMessage":"outgoingHighWaterMark cannot be negative","messagePattern":"outgoingHighWaterMark cannot be negative","errorType":"exception","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"ext/web/webtransport.js","lineNumber":857,"sourceCode":"      throw new RangeError(\"incomingHighWaterMark cannot be negative\");\n    }\n    if (value < 1) value = 1;\n    this.#incomingHighWaterMark = value;\n  }\n\n  get outgoingHighWaterMark() {\n    webidl.assertBranded(this, WebTransportDatagramDuplexStreamPrototype);\n    return this.#outgoingHighWaterMark;\n  }\n\n  set outgoingHighWaterMark(value) {\n    webidl.assertBranded(this, WebTransportDatagramDuplexStreamPrototype);\n    value = webidl.converters[\"unrestricted double\"](\n      value,\n      \"Failed to execute 'outgoingHighWaterMark' on 'WebTransportDatagramDuplexStream'\",\n    );\n    if (value < 0 || NumberIsNaN(value)) {\n      throw new RangeError(\"outgoingHighWaterMark cannot be negative\");\n    }\n    if (value < 1) value = 1;\n    this.#outgoingHighWaterMark = value;\n  }\n\n  get maxDatagramSize() {\n    webidl.assertBranded(this, WebTransportDatagramDuplexStreamPrototype);\n    if (this.#conn) {\n      return this.#conn.maxDatagramSize - this.#sessionIdBuf.length;\n    }\n    return 1024;\n  }\n\n  get readable() {\n    webidl.assertBranded(this, WebTransportDatagramDuplexStreamPrototype);\n    if (!this.#readable) {\n      this.#readable = new ReadableStream({\n        type: \"bytes\",","sourceCodeStart":839,"sourceCodeEnd":875,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/web/webtransport.js#L839-L875","documentation":"WebTransportDatagramDuplexStream.outgoingHighWaterMark sizes the buffer/queue threshold for outgoing datagrams. Its setter in ext/web/webtransport.js takes an 'unrestricted double' and throws a RangeError when assigned a negative value or NaN. As with the incoming variant, values below 1 are clamped to 1 rather than erroring.","triggerScenarios":"duplex.outgoingHighWaterMark = -1; NaN from math on undefined inputs; user-provided buffer sizes forwarded without validation.","commonSituations":"Performance-tuning knobs copied from other transports where 0 or -1 means 'default'; config reload paths assigning raw values; dividing by a variable that can be 0 producing Infinity-like or NaN edge cases.","solutions":["Set a positive finite number appropriate for your datagram burst size.","Replace negative sentinels with a real default before assignment.","Validate with Number.isFinite(v) && v >= 0 first.","Remember 0 is clamped to 1 — use a meaningful positive value instead."],"exampleFix":"// before\nduplex.outgoingHighWaterMark = size; // size can be -1 from config\n\n// after\nduplex.outgoingHighWaterMark =\n  Number.isFinite(size) && size >= 1 ? size : 1;","handlingStrategy":"validation","validationCode":"function toHighWaterMark(v, fallback = 1) {\n  return Number.isFinite(v) && v >= 1 ? v : fallback;\n}\nduplex.outgoingHighWaterMark = toHighWaterMark(cfg.outHwm);","typeGuard":"function isValidHighWaterMark(v) {\n  return typeof v === \"number\" && Number.isFinite(v) && v >= 0;\n}","tryCatchPattern":"try { duplex.outgoingHighWaterMark = v; } catch (e) { if (e instanceof RangeError) duplex.outgoingHighWaterMark = 1; else throw e; }","preventionTips":["Reject or clamp buffer-size config before it reaches the setter.","Do not reuse '0/-1 means default' conventions from other transports.","Keep all datagram tuning assignments behind one validated helper."],"tags":["webtransport","datagrams","backpressure","validation","rangeerror"],"backgroundTag":"negative-value-rejected","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-31T09:17:48.483Z"}