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

  1. Clamp/validate layer to the range [0, texture.depth - 1] before uploading
  2. Fix off-by-one loop bounds when uploading layers sequentially
  3. Coerce string indices with Number() and check Number.isInteger
  4. 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

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


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/3ad578487aaed3cd. Report an issue: GitHub.