{"record":{"id":"d67f2aeeacd2b5c2","repo":"denoland/deno","slug":"incomingmaxage-cannot-be-negative","errorCode":null,"errorMessage":"incomingMaxAge cannot be negative","messagePattern":"incomingMaxAge cannot be negative","errorType":"exception","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"ext/web/webtransport.js","lineNumber":803,"sourceCode":"      promise.resolve(undefined);\n    }\n\n    this.#sending = false;\n  }\n\n  get incomingMaxAge() {\n    webidl.assertBranded(this, WebTransportDatagramDuplexStreamPrototype);\n    return this.#incomingMaxAge;\n  }\n\n  set incomingMaxAge(value) {\n    webidl.assertBranded(this, WebTransportDatagramDuplexStreamPrototype);\n    value = webidl.converters[\"unrestricted double?\"](\n      value,\n      \"Failed to execute 'incomingMaxAge' on 'WebTransportDatagramDuplexStream'\",\n    );\n    if (value < 0 || NumberIsNaN(value)) {\n      throw new RangeError(\"incomingMaxAge cannot be negative\");\n    }\n    if (value === 0) value = null;\n    this.#incomingMaxAge = value;\n  }\n\n  get outgoingMaxAge() {\n    webidl.assertBranded(this, WebTransportDatagramDuplexStreamPrototype);\n    return this.#outgoingMaxAge;\n  }\n\n  set outgoingMaxAge(value) {\n    webidl.assertBranded(this, WebTransportDatagramDuplexStreamPrototype);\n    value = webidl.converters[\"unrestricted double?\"](\n      value,\n      \"Failed to execute 'outgoingMaxAge' on 'WebTransportDatagramDuplexStream'\",\n    );\n    if (value < 0 || NumberIsNaN(value)) {\n      throw new RangeError(\"outgoingMaxAge cannot be negative\");","sourceCodeStart":785,"sourceCodeEnd":821,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/web/webtransport.js#L785-L821","documentation":"WebTransportDatagramDuplexStream.incomingMaxAge is a writable property (an 'unrestricted double?' in IDL) that caps how old received datagrams may be. Deno's setter in ext/web/webtransport.js rejects negative values and NaN with a RangeError. Zero is normalized to null (no age limit). The check happens in the setter, so even assigning from a computation throws synchronously.","triggerScenarios":"duplex.incomingMaxAge = -1 or a NaN from a bad calculation like undefined * 1000; reading a config value in milliseconds where a '-1 means unset' convention collides with this API; subtracting a larger baseline from a smaller timestamp.","commonSituations":"Translating config sentinels (-1 for 'default') from other APIs into WebTransport options; NaN leaking from optional fields ('maxAge: undefined' times a unit factor); unit conversions producing negative values when inputs are misordered.","solutions":["Pass a non-negative number of milliseconds, or null for no limit.","Map config sentinels explicitly: negative or missing means null, not -1.","Guard computed values: Number.isFinite(v) && v >= 0 before assigning.","Remember 0 is treated as null (disabled), not as 'expire immediately'."],"exampleFix":"// before\nduplex.incomingMaxAge = config.maxAgeMs ?? -1; // -1 sentinel throws\n\n// after\nduplex.incomingMaxAge =\n  config.maxAgeMs != null && config.maxAgeMs > 0 ? config.maxAgeMs : null;","handlingStrategy":"validation","validationCode":"function toMaxAge(v) {\n  return Number.isFinite(v) && v > 0 ? v : null;\n}\nduplex.incomingMaxAge = toMaxAge(config.maxAgeMs);","typeGuard":"function isValidMaxAge(v) {\n  return v == null || (typeof v === \"number\" && Number.isFinite(v) && v >= 0);\n}","tryCatchPattern":"try { duplex.incomingMaxAge = v; } catch (e) { if (e instanceof RangeError) duplex.incomingMaxAge = null; else throw e; }","preventionTips":["Map config sentinels (-1/undefined) to null at the boundary.","Remember 0 is normalized to null, not 'expire now'.","Validate all numeric datagram tuning with Number.isFinite checks before assignment."],"tags":["webtransport","datagrams","validation","rangeerror"],"backgroundTag":"negative-value-rejected","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}