BabylonJS/Babylon.js · error · Error
Layer ${layer} is out of range for a 2D array texture with $
Error message
Layer ${layer} is out of range for a 2D array texture with ${texture.depth} layers. What it means
After confirming an internal texture exists, UploadImageToTexture2DArrayLayer validates that the target layer index is a non-negative integer strictly less than the texture's depth (layer count). Any out-of-range or non-integer layer throws with a message naming the requested layer and the texture's layer count.
Source
Thrown at packages/dev/core/src/Materials/Textures/rawTexture2DArray.functions.ts:61
imageBitmapOptions?: ImageBitmapOptions;
}
/**
* Uploads a decoded image source (ImageBitmap, canvas, video, image element...) into a single layer of a 2D array texture.
* This is the image-source counterpart to RawTexture2DArray.update, which only accepts raw bytes.
* @param texture defines the 2D array texture to upload into
* @param source defines the image source to upload
* @param layer defines the array layer to upload into
* @param options defines optional upload settings (invertY, premultiplyAlpha)
*/
export function UploadImageToTexture2DArrayLayer(texture: RawTexture2DArray, source: ImageSource, layer: number, options?: IUploadImageToTexture2DArrayLayerOptions): void {
const internalTexture = texture.getInternalTexture();
if (!internalTexture) {
throw new Error("Cannot upload to a 2D array texture that has no internal texture.");
}
if (!Number.isInteger(layer) || layer < 0 || layer >= texture.depth) {
throw new Error(`Layer ${layer} is out of range for a 2D array texture with ${texture.depth} layers.`);
}
const scene = texture.getScene();
if (!scene) {
throw new Error("Cannot upload to a 2D array texture that is not attached to a scene.");
}
const engine = scene.getEngine();
// updateTextureArrayLayerFromImageSource is an opt-in engine extension. When the consumer never
// imported it, the augmented method is missing, so fail early with the standard side-effect import
// message (matching the engine.rawTexture family) instead of a generic "is not a function" error.
if (!_IsSideEffectImplemented(engine.updateTextureArrayLayerFromImageSource)) {
throw _WarnImport("engine.texture2DArrayImageSource");
}
engine.updateTextureArrayLayerFromImageSource(internalTexture, source, layer, options?.invertY ?? false, options?.premultiplyAlpha ?? false);
}
View on GitHub (pinned to 0592b347b8)
Solutions
- Clamp/validate layer to the range [0, texture.depth - 1] before uploading
- Fix off-by-one loop bounds when uploading layers sequentially
- Coerce string indices with Number() and check Number.isInteger
- Log texture.depth at the call site to confirm expected layer count
Example fix
// before UploadImageToTexture2DArrayLayer(tex, bitmaps[i], i + 1); // after if (i + 1 < tex.depth) UploadImageToTexture2DArrayLayer(tex, bitmaps[i], i + 1);
Defensive patterns
Strategy: validation
Validate before calling
function uploadLayer(tex, source, layer) {
if (!Number.isInteger(layer) || layer < 0 || layer >= tex.depth) {
throw new RangeError(`layer ${layer} out of [0, ${tex.depth})`);
}
UploadImageToTexture2DArrayLayer(tex, source, layer);
} Type guard
function isValidLayer(layer: unknown, depth: number): layer is number {
return typeof layer === "number" && Number.isInteger(layer) && layer >= 0 && layer < depth;
} Try / catch
try {
UploadImageToTexture2DArrayLayer(tex, bitmap, layer);
} catch (e) {
if (e instanceof Error && e.message.includes("out of range")) {
console.error(`Bad layer ${layer}; texture depth=${tex.depth}`);
} else throw e;
} Prevention
- Clamp layer indices to [0, depth - 1]
- Check loop bounds for off-by-one errors
- Convert string indices to integers and validate
When it happens
Trigger: Calling UploadImageToTexture2DArrayLayer with layer >= texture.depth, a negative layer, a fractional layer, or NaN — e.g. indexing into an array texture built from N images with layer N (off-by-one) or a parsed string index.
Common situations: Off-by-one loops over layers, parseInt results, indices derived from a different texture's depth, or mixing up 0-based vs 1-based layer numbering.
Related errors
- Image url is not set
- Sample2DRgbaToRef: widthPx and heightPx must be positive.
- Sample2DRgbaToRef: data length (${data.length}) is less than
- Unable to get 2d context
- Nothing else parsed so far
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/3ad578487aaed3cd.
Report an issue: GitHub.