BabylonJS/Babylon.js · error · Error

Cannot upload to a 2D array texture that is not attached to

Error message

Cannot upload to a 2D array texture that is not attached to a scene.

What it means

Uploading requires the owning scene and its engine to invoke the GPU upload path. If texture.getScene() returns null/undefined the wrapper is detached (or never attached), so the library throws instead of dereferencing the scene.

Source

Thrown at packages/dev/core/src/Materials/Textures/rawTexture2DArray.functions.ts:66

 * 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);
}

/**
 * Fetches an image from a url, decodes it and uploads it into a single layer of a 2D array texture.
 * @param texture defines the 2D array texture to upload into
 * @param url defines the url of the image to load
 * @param layer defines the array layer to upload into

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Ensure the upload happens while the scene is still alive; cancel pending async uploads on scene disposal
  2. Pass a valid Scene when creating the RawTexture2DArray
  3. Recreate the texture attached to the current scene if it was disposed
  4. Check scene.isDisposed before uploading

Example fix

// before
createImageBitmap(blob).then(b => UploadImageToTexture2DArrayLayer(tex, b, layer));
// after
createImageBitmap(blob).then(b => {
  if (tex.isDisposed() || !tex.getScene()) return;
  UploadImageToTexture2DArrayLayer(tex, b, layer);
});
Defensive patterns

Strategy: validation

Validate before calling

const scene = texture.getScene();
if (!scene || scene.isDisposed) {
  console.warn("Skipping upload: texture not attached to a live scene");
} else {
  UploadImageToTexture2DArrayLayer(texture, bitmap, layer);
}

Type guard

function isAttachedToLiveScene(t: RawTexture2DArray): boolean {
  const s = t.getScene();
  return !!s && !s.isDisposed;
}

Try / catch

try {
  UploadImageToTexture2DArrayLayer(tex, bitmap, 0);
} catch (e) {
  if (e instanceof Error && e.message.includes("not attached to a scene")) {
    // scene disposed (e.g. HMR/unmount) — abort upload quietly
  } else throw e;
}

Prevention

When it happens

Trigger: Calling UploadImageToTexture2DArrayLayer on a texture whose scene reference is gone — e.g. after the texture was disposed and detached, or the texture was constructed without a live scene.

Common situations: Uploading in an async callback after the scene was disposed (HMR reload, component unmount), or a texture moved between scenes losing its reference.

Related errors


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