{"record":{"id":"ce7cbe2143869d59","repo":"BabylonJS/Babylon.js","slug":"bit-index-out-of-range","errorCode":null,"errorMessage":"Bit index out of range","messagePattern":"Bit index out of range","errorType":"exception","errorClass":"RangeError","httpStatus":null,"severity":"error","filePath":"packages/dev/core/src/Misc/bitArray.ts","lineNumber":32,"sourceCode":"export class BitArray {\r\n    private readonly _byteArray: Uint8Array;\r\n\r\n    /**\r\n     * Creates a new bit array with a fixed size.\r\n     * @param size The number of bits to store.\r\n     */\r\n    public constructor(public readonly size: number) {\r\n        this._byteArray = new Uint8Array(Math.ceil(this.size / 8));\r\n    }\r\n\r\n    /**\r\n     * Gets the current value at the specified index.\r\n     * @param bitIndex The index to get the value from.\r\n     * @returns The value at the specified index.\r\n     */\r\n    public get(bitIndex: number): boolean {\r\n        if (bitIndex >= this.size) {\r\n            throw new RangeError(\"Bit index out of range\");\r\n        }\r\n        const byteIndex = GetByteIndex(bitIndex);\r\n        const bitMask = GetBitMask(bitIndex);\r\n        return (this._byteArray[byteIndex] & bitMask) !== 0;\r\n    }\r\n\r\n    /**\r\n     * Sets the value at the specified index.\r\n     * @param bitIndex The index to set the value at.\r\n     * @param value The value to set.\r\n     */\r\n    public set(bitIndex: number, value: boolean): void {\r\n        if (bitIndex >= this.size) {\r\n            throw new RangeError(\"Bit index out of range\");\r\n        }\r\n        const byteIndex = GetByteIndex(bitIndex);\r\n        const bitMask = GetBitMask(bitIndex);\r\n        if (value) {\r","sourceCodeStart":14,"sourceCodeEnd":50,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/core/src/Misc/bitArray.ts#L14-L50","documentation":"BitArray.get() validates that the requested bit index is within the array's declared size before computing the byte offset and bitmask. Reading at or beyond size would read bytes outside the backing array, so the library throws a RangeError instead of returning garbage.","triggerScenarios":"Calling bitArray.get(i) where i >= bitArray.size — e.g. indexing with a loop bound from a different array, or a BitArray constructed with too small a size for the data being read.","commonSituations":"Off-by-one loop conditions (i <= size instead of i < size); deserializing data written with a larger BitArray; sharing one index variable across differently sized BitArrays.","solutions":["Check the index against bitArray.size before calling get (valid indexes are 0..size-1)","Fix loop bounds to use `for (let i = 0; i < bitArray.size; i++)`","Construct/resize the BitArray with a size large enough for all indexes you will read"],"exampleFix":"// before\nconst value = bitArray.get(index); // index may equal size\n// after\nconst value = index < bitArray.size ? bitArray.get(index) : false;","handlingStrategy":"validation","validationCode":"if (bitIndex < 0 || bitIndex >= bitArray.size) throw new RangeError(`bitIndex ${bitIndex} outside 0..${bitArray.size - 1}`);","typeGuard":"function inRange(bits: { size: number }, i: number): boolean {\n  return Number.isInteger(i) && i >= 0 && i < bits.size;\n}","tryCatchPattern":"try {\n  return bitArray.get(bitIndex);\n} catch (e) {\n  if (e instanceof RangeError) {\n    console.warn(`Bit index ${bitIndex} >= size ${bitArray.size}; returning false`);\n    return false;\n  }\n  throw e;\n}","preventionTips":["Iterate with `i < size` bounds, never `i <= size`","Clamp or validate external indexes before calling get","Keep producer and consumer BitArray sizes in sync when deserializing"],"tags":["range-error","bitarray","bounds-check"],"backgroundTag":"index-out-of-range","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}