{"record":{"id":"82c523dd899e4d86","repo":"denoland/deno","slug":"err-out-of-range-82c523","errorCode":"ERR_OUT_OF_RANGE","errorMessage":"The value of \"id\" is out of range. It must be > 0 and <= ${kMaxStreams}. Received ${id}","messagePattern":"The value of \"id\" is out of range\\. It must be > 0 and <= (.+?)\\. Received (.+?)","errorType":"exception","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"ext/node/polyfills/http2.ts","lineNumber":4157,"sourceCode":"      return;\n    }\n    if (this[kTimeout]) {\n      this[kTimeout].refresh();\n      syncSessionTimeoutInspectLinks(this[kTimeout]);\n    }\n  }\n\n  // Sets the id of the next stream to be created by this Http2Session.\n  // The value must be a number in the range 0 <= n <= kMaxStreams. The\n  // value also needs to be larger than the current next stream ID.\n  setNextStreamID(id) {\n    if (this.destroyed) {\n      throw new ERR_HTTP2_INVALID_SESSION();\n    }\n\n    validateNumber(id, \"id\");\n    if (id <= 0 || id > kMaxStreams) {\n      throw new ERR_OUT_OF_RANGE(\"id\", `> 0 and <= ${kMaxStreams}`, id);\n    }\n    this[kHandle].setNextStreamID(id);\n  }\n\n  // Sets the local window size (local endpoints's window size)\n  // Returns 0 if success or throw an exception if NGHTTP2_ERR_NOMEM\n  // if the window allocation fails\n  setLocalWindowSize(windowSize) {\n    if (this.destroyed) {\n      throw new ERR_HTTP2_INVALID_SESSION();\n    }\n\n    validateInt32(windowSize, \"windowSize\", 0);\n    const ret = this[kHandle].setLocalWindowSize(windowSize);\n\n    if (ret === NGHTTP2_ERR_NOMEM) {\n      this.destroy(new Error(\"HTTP2 session out of memory\"));\n    }","sourceCodeStart":4139,"sourceCodeEnd":4175,"githubUrl":"https://github.com/denoland/deno/blob/9ad36f7a2cce60488e6ec52283efb32efddaf93a/ext/node/polyfills/http2.ts#L4139-L4175","documentation":"setNextStreamID() validates that id is a number strictly greater than 0 and at most kMaxStreams (2**32 - 1 = 4294967295), the full 32-bit HTTP/2 stream-ID space. The message interpolates both bounds. Note that validateNumber() runs first, so a non-number or NaN fails earlier with ERR_INVALID_ARG_TYPE, and nghttp2 additionally requires client-initiated stream IDs to be odd.","triggerScenarios":"session.setNextStreamID(0), a negative id, a fractional id like 1.5, or any value above 4294967295; also computing the next id with an overflow or bitwise expression that wraps past 2**32.","commonSituations":"Seeding the id from a counter that starts at 0; deriving it via (lastId * 2) growth that overflows 32 bits; copying server-side even IDs into a client session where odd IDs are required anyway.","solutions":["Pass a positive integer in 1..4294967295, odd and larger than the current nextStreamID for client sessions","If you only need 'the next odd id', pass id = lastStreamID + 2 and verify it stays under 2**32","Clamp or reject the computed id before calling setNextStreamID"],"exampleFix":"// before\nsession.setNextStreamID(0);\n\n// after\nconst kMaxStreams = 2 ** 32 - 1;\nif (nextId > 0 && nextId <= kMaxStreams) session.setNextStreamID(nextId);","handlingStrategy":"validation","validationCode":"const kMaxStreams = 2 ** 32 - 1;\nif (!Number.isInteger(id) || id <= 0 || id > kMaxStreams) {\n  throw new RangeError(`bad next stream id: ${id}`);\n}\nsession.setNextStreamID(id);","typeGuard":"function isValidStreamId(id) {\n  return Number.isInteger(id) && id > 0 && id <= 2 ** 32 - 1;\n}","tryCatchPattern":null,"preventionTips":["Client-initiated stream IDs must be odd — compute nextId as lastOddId + 2","Range-check computed IDs before calling; overflow past 2**32 is a bug in the caller's math","Never seed from a zero-based counter"],"tags":["http2","node-compat","argument-validation"],"backgroundTag":"argument-out-of-range","analyzedSha":"9ad36f7a2cce60488e6ec52283efb32efddaf93a","analyzedAt":"2026-08-20T13:07:44.778Z","schemaVersion":2},"datasetVersion":"2026-08-28T16:17:29.566Z"}