{"record":{"id":"a6ce9ba6fade980f","repo":"dotnet/runtime","slug":"index-out-of-range","errorCode":null,"errorMessage":"index out of range","messagePattern":"index out of range","errorType":"validation","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/mono/browser/runtime/roots.ts","lineNumber":184,"sourceCode":"    private __offset: VoidPtr;\n    private __offset32: number;\n    private __handle: number;\n    private __ownsAllocation: boolean;\n\n    constructor (offset: VoidPtr, capacity: number, ownsAllocation: boolean, name?: string) {\n        const capacityBytes = capacity * 4;\n\n        this.__offset = offset as any >>> 0 as any;\n        this.__offset32 = <number><any>offset >>> 2;\n        this.__count = capacity;\n        this.length = capacity;\n        mono_assert(!WasmEnableThreads || !gc_locked, \"GC must not be locked when creating a GC root\");\n        this.__handle = cwraps.SystemInteropJS_RegisterGCRoot(offset, capacityBytes, name || \"noname\");\n        this.__ownsAllocation = ownsAllocation;\n    }\n\n    _throw_index_out_of_range (): void {\n        throw new Error(\"index out of range\");\n    }\n\n    _check_in_range (index: number): void {\n        if ((index >= this.__count) || (index < 0))\n            this._throw_index_out_of_range();\n    }\n\n    get_address (index: number): MonoObjectRef {\n        this._check_in_range(index);\n        return <any>this.__offset + (index * 4);\n    }\n\n    get_address_32 (index: number): number {\n        this._check_in_range(index);\n        return this.__offset32 + index;\n    }\n\n    // NOTE: These functions do not use the helpers from memory.ts because WasmRoot.get and WasmRoot.set","sourceCodeStart":166,"sourceCodeEnd":202,"githubUrl":"https://github.com/dotnet/runtime/blob/60108ba66eb7d1d12f595480091b4ad80a24b172/src/mono/browser/runtime/roots.ts#L166-L202","documentation":"Thrown by WasmRootBufferImpl._throw_index_out_of_range (via _check_in_range) when a get/set/get_address/copy operation is given an index that is < 0 or >= the buffer's capacity. It is the standard bounds-check for the root-buffer array accessors.","triggerScenarios":"Calling buf.get(i), buf.set(i, v), buf.get_address(i), buf.copy_value_from_address(i, ...) with i outside [0, capacity). Common with an off-by-one loop bound or a stale capacity after release().","commonSituations":"Looping with <= instead of <; using an index computed from a different-sized structure; reading length after the buffer was released (capacity collapses to 0); passing a raw pointer offset where an index was expected.","solutions":["Check 0 <= index < buffer.length (or __count) before accessing.","Use exclusive upper bounds in loops: for (let i = 0; i < buf.length; i++).","Ensure the buffer has not been released before indexing into it."],"exampleFix":"// before\nfor (let i = 0; i <= buf.length; i++) buf.get(i); // off-by-one\n// after\nfor (let i = 0; i < buf.length; i++) buf.get(i);","handlingStrategy":"validation","validationCode":"function safeGet(buf: WasmRootBuffer, index: number) {\n  if (index < 0 || index >= buf.length) throw new RangeError(`index ${index} out of [0,${buf.length})`);\n  return buf.get(index);\n}","typeGuard":"function inRange(buf: { length: number }, i: unknown): i is number {\n  return typeof i === 'number' && Number.isInteger(i) && i >= 0 && i < buf.length;\n}","tryCatchPattern":null,"preventionTips":["Use exclusive upper bounds: i < buf.length.","Re-check length right before indexing if the buffer may have been released.","Do not mix raw pointer offsets with root-buffer indices."],"tags":["gc-roots","bounds-check","validation","argument-error"],"backgroundTag":null,"analyzedSha":"60108ba66eb7d1d12f595480091b4ad80a24b172","analyzedAt":"2026-08-10T18:54:11.478Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}