BabylonJS/Babylon.js · error
updateWrappedNativeTexture: new handle dimensions (${newWidt
Error message
updateWrappedNativeTexture: new handle dimensions (${newWidth}x${newHeight}) must match the wrapped texture's dimensions (${internalTexture.baseWidth}x${internalTexture.baseHeight}). What it means
updateWrappedNativeTexture requires the new native texture handle to have exactly the same dimensions as the wrapped InternalTexture (baseWidth/baseHeight), because bgfx framebuffers and engine caches bake the size into state that is not rebuilt here.
Source
Thrown at packages/dev/core/src/Engines/thinNativeEngine.pure.ts:2164
* texture and call {@link wrapNativeTexture} again. Sampling mode and mip-map flag are properties of the logical
* wrapped texture and are re-applied to the new resource. Any render-target wrapper holding this texture as its
* color attachment has its framebuffer rebuilt with the new handle.
*
* Throws if the target was not produced by {@link wrapNativeTexture}, if the new handle's dimensions don't match,
* if the wrapped texture is part of a multi render-target, or if the wrapper has a depth/stencil texture (these
* are not supported in this version; dispose and re-wrap).
* @param internalTexture defines the wrapped InternalTexture to repoint
* @param texture defines the new native texture handle to wrap
*/
public updateWrappedNativeTexture(internalTexture: InternalTexture, texture: NativeTexture): void {
if (internalTexture.source !== InternalTextureSource.External) {
throw new Error("updateWrappedNativeTexture: target InternalTexture was not produced by wrapNativeTexture.");
}
const newWidth = this._engine.getTextureWidth(texture);
const newHeight = this._engine.getTextureHeight(texture);
if (newWidth !== internalTexture.baseWidth || newHeight !== internalTexture.baseHeight) {
throw new Error(
`updateWrappedNativeTexture: new handle dimensions (${newWidth}x${newHeight}) must match the wrapped texture's dimensions (${internalTexture.baseWidth}x${internalTexture.baseHeight}).`
);
}
if (this._engine.getTextureLayerCount) {
const newLayerCount = this._engine.getTextureLayerCount(texture);
const oldLayerCount = internalTexture.is2DArray ? internalTexture.depth : 1;
if (newLayerCount !== oldLayerCount) {
throw new Error(`updateWrappedNativeTexture: new handle layer count (${newLayerCount}) must match the wrapped texture's layer count (${oldLayerCount}).`);
}
}
// Pre-validate before mutating any state so a thrown precondition leaves the InternalTexture untouched.
// Note: rtWrapper.texture only returns _textures[0]; walk every attachment to catch the multi-RT case where
// the wrapped texture is at index > 0.
for (const rtWrapper of this._renderTargetWrapperCache) {
if (!rtWrapper.textures?.includes(internalTexture)) {
continue;
}
View on GitHub (pinned to 0592b347b8)
Solutions
- Dispose the wrapped texture and call wrapNativeTexture again with the new handle and its actual dimensions.
- Recreate the new native texture at the original dimensions before updating.
- Update dependent render targets and viewport state after recreating at the new size.
Example fix
// before engine.updateWrappedNativeTexture(wrapped, resizedNativeTex); // throws on size mismatch // after wrapped.dispose(); const wrapped2 = engine.wrapNativeTexture(resizedNativeTex, newW, newH, ...);
Defensive patterns
Strategy: validation
Validate before calling
const w = engine._engine.getTextureWidth(newNativeTex);
const h = engine._engine.getTextureHeight(newNativeTex);
if (w !== wrapped.baseWidth || h !== wrapped.baseHeight) {
throw new Error(`Resize mismatch: ${w}x${h} vs ${wrapped.baseWidth}x${wrapped.baseHeight}; dispose and re-wrap.`);
} Try / catch
try {
engine.updateWrappedNativeTexture(wrapped, newNativeTex);
} catch (e) {
if (e.message.includes("dimensions")) {
wrapped.dispose();
wrapped = engine.wrapNativeTexture(newNativeTex, newW, newH, sampling, ...);
} else throw e;
} Prevention
- On resize events, always dispose + re-wrap rather than updating in place.
- Store expected dimensions alongside wrapped handles and assert before updates.
- Pin render-target sizes during a frame; resize only between frames with full re-wrap.
When it happens
Trigger: engine.updateWrappedNativeTexture(wrapped, newNativeTex) where engine._engine.getTextureWidth/Height(newNativeTex) differ from wrapped.baseWidth/baseHeight, e.g. after resizing an offscreen render target.
Common situations: Window/resize events recreate a native texture at a new resolution and the caller tries to swap it into the existing wrapped texture instead of disposing and re-wrapping at the new size.
Related errors
- updateWrappedNativeTexture: target InternalTexture was not p
- updateWrappedNativeTexture: new handle layer count (${newLay
- updateWrappedNativeTexture: wrapped texture is part of a mul
- updateWrappedNativeTexture: wrapped texture's render-target
- updateWrappedWebGLTexture: target InternalTexture was not pr
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/260b8fd7c429a8d6.
Report an issue: GitHub.