{"record":{"id":"30cfacab12240588","repo":"BabylonJS/Babylon.js","slug":"method-local-range-offset-offset-coun","errorCode":null,"errorMessage":"${method}: local range [${offset}, ${offset + count}) is outside the reserved region [0, ${state.capacity})","messagePattern":"(.+?): local range \\[(.+?), (.+?)\\) is outside the reserved region \\[0, (.+?)\\)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"packages/dev/core/src/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.ts","lineNumber":2194,"sourceCode":"        const compound = this;\r\n        const applyBounds = () => {\r\n            if (boundsMin.x <= boundsMax.x) {\r\n                proxy.setBoundingInfo(new BoundingInfo(boundsMin.clone(), boundsMax.clone()));\r\n                compound._updateBoundingInfoFromProxies();\r\n            }\r\n        };\r\n        // Rejects any mutating call after the part was removed, so a retained stale handle can't touch a surviving\r\n        // part that inherited this region's (now-reused) part index/base.\r\n        const assertLive = (method: string) => {\r\n            if (state.removed) {\r\n                throw new Error(`${method}: this streaming part has been removed`);\r\n            }\r\n        };\r\n        // Enforces the documented local part boundary [0, capacity) so a handle call can never address another\r\n        // part's atlas region (the region base is added to these local coordinates before use).\r\n        const assertLocalRange = (method: string, offset: number, count: number) => {\r\n            if (!Number.isInteger(offset) || !Number.isInteger(count) || offset < 0 || count < 0 || offset + count > state.capacity) {\r\n                throw new Error(`${method}: local range [${offset}, ${offset + count}) is outside the reserved region [0, ${state.capacity})`);\r\n            }\r\n        };\r\n\r\n        const handle: IGaussianSplattingStreamingPart = {\r\n            proxy,\r\n            capacity,\r\n            get partIndex() {\r\n                return state.partIndex;\r\n            },\r\n            get base() {\r\n                return state.base;\r\n            },\r\n            get centersTexture() {\r\n                return compound.centersTexture;\r\n            },\r\n            get covariancesATexture() {\r\n                return compound.covariancesATexture;\r\n            },\r","sourceCodeStart":2176,"sourceCodeEnd":2212,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/core/src/Meshes/GaussianSplatting/gaussianSplattingMesh.pure.ts#L2176-L2212","documentation":"Streaming part writes are expressed in local coordinates [0, capacity) of the reserved region; the handle adds the region base internally. assertLocalRange throws when offset/count are non-integers, negative, or offset+count exceeds the part's reserved capacity, preventing a handle from addressing a neighboring part's texels.","triggerScenarios":"Calling a part's write method with offset or count beyond the capacity returned when the part was reserved, with fractional values, or with negative values.","commonSituations":"Assuming capacity equals the full atlas size; off-by-one errors (offset + count == capacity is valid, > capacity is not); reserving a smaller part than the producer emits.","solutions":["Use offset/count values within the capacity returned by reserveStreamingPart and clamp offset + count to capacity","Validate Number.isInteger(offset) && Number.isInteger(count) && offset >= 0 && count >= 0 before calling","Split large writes into chunks that fit the reserved region"],"exampleFix":"// before\npart.writeSplats(globalOffset, data); // atlas-level offset\n// after\nconst local = globalOffset - partBase;\nif (local >= 0 && local + data.length / 32 <= part.capacity) {\n    part.writeSplats(local, data);\n}","handlingStrategy":"validation","validationCode":"const ok = Number.isInteger(offset) && Number.isInteger(count) && offset >= 0 && count >= 0 && offset + count <= part.capacity;\nif (!ok) throw new RangeError(`[${offset}, ${offset + count}) outside [0, ${part.capacity})`);","typeGuard":"const inRange = (o: number, c: number, cap: number) =>\n  Number.isInteger(o) && Number.isInteger(c) && o >= 0 && c >= 0 && o + c <= cap;","tryCatchPattern":"try {\n  handle.writeSplats(offset, data);\n} catch (e) {\n  if (String(e).includes('outside the reserved region')) {\n    const n = Math.floor((handle.capacity - offset));\n    if (n > 0) handle.writeSplats(offset, data.subarray(0, n * 32));\n  } else throw e;\n}","preventionTips":["Always express writes in local part coordinates, never atlas-global ones","Clamp count to capacity - offset before writing","Keep the part's returned capacity alongside the handle"],"tags":["gaussian-splatting","bounds-check","validation"],"backgroundTag":"range-out-of-bounds","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}