BabylonJS/Babylon.js · error · Error
Cannot upload to a 2D array texture that has no internal tex
Error message
Cannot upload to a 2D array texture that has no internal texture.
What it means
UploadImageToTexture2DArrayLayer uploads an image source into one layer of a RawTexture2DArray via its underlying InternalTexture. If the array texture has not been given GPU storage yet (no internal texture), there is nothing to upload into, so the call throws.
Source
Thrown at packages/dev/core/src/Materials/Textures/rawTexture2DArray.functions.ts:57
samplingMode?: number;
/** Defines the texture type (Constants.TEXTURETYPE_UNSIGNED_BYTE by default) */
textureType?: number;
/** Options forwarded to createImageBitmap when decoding each url */
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");
}
View on GitHub (pinned to 0592b347b8)
Solutions
- Create the RawTexture2DArray with valid width/height/depth so an internal texture is allocated before uploading
- Check texture.getInternalTexture() is non-null before uploading
- Ensure the texture has not been disposed before uploading
- Recreate the texture if it was disposed
Example fix
// before const tex = new RawTexture2DArray(null, 0, 0, 4, Constants.TEXTUREFORMAT_RGBA, scene); UploadImageToTexture2DArrayLayer(tex, bitmap, 0); // after const tex = new RawTexture2DArray(data, width, height, layerCount, Constants.TEXTUREFORMAT_RGBA, scene); tex.createInt8ArrayTextureIfNeeded?.() ?? tex.getInternalTexture(); UploadImageToTexture2DArrayLayer(tex, bitmap, 0);
Defensive patterns
Strategy: validation
Validate before calling
if (!texture.getInternalTexture()) {
throw new Error("Texture has no internal texture; create it with valid dimensions first");
}
UploadImageToTexture2DArrayLayer(texture, source, layer); Type guard
function isUploadable(t: RawTexture2DArray): boolean {
return t.getInternalTexture() !== null && !t.isDisposed();
} Try / catch
try {
UploadImageToTexture2DArrayLayer(texture, bitmap, 0);
} catch (e) {
if (e instanceof Error && e.message.includes("no internal texture")) {
recreateTextureAndRetry();
} else throw e;
} Prevention
- Always create RawTexture2DArray with concrete width/height/depth
- Check getInternalTexture() before GPU uploads
- Do not upload to disposed textures
When it happens
Trigger: Calling UploadImageToTexture2DArrayLayer (or LoadImageToTexture2DArrayLayerAsync / CreateTexture2DArrayFromImageUrlsAsync) on a RawTexture2DArray constructed without dimensions or whose internal texture was never created/disposed.
Common situations: Creating the array texture with a factory that defers allocation, calling upload after texture.dispose(), or a failed creation path that left the wrapper without an internal texture.
Related errors
- FrameGraphRenderTarget.renderTargetWrapper: Failed to get te
- Cannot upload to a 2D array texture that is not attached to
- There is no NavMesh generated.
- There is no TileCache generated.
- No volume subnode
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/82c2d1405366bcda.
Report an issue: GitHub.