BabylonJS/Babylon.js · critical
Engine is disposed
Error message
Engine is disposed
What it means
_createRenderTargetTexture builds a Babylon RenderTargetTexture around the XR layer's framebuffer/color texture. The provider stores an engine reference; if the engine was disposed (reference cleared), creating new GPU resources is impossible and this error is thrown before any allocation.
Source
Thrown at packages/dev/core/src/XR/webXRWebGLRenderTargetTextureProvider.ts:38
}
const internalTexture = new InternalTexture(this._engine, InternalTextureSource.Unknown, true);
internalTexture.width = textureSize.width;
internalTexture.height = textureSize.height;
internalTexture._hardwareTexture = new WebGLHardwareTexture(texture, gl);
internalTexture.isReady = true;
return internalTexture;
}
protected _createRenderTargetTexture(
width: number,
height: number,
framebuffer: Nullable<WebGLFramebuffer>,
colorTexture?: WebGLTexture,
depthStencilTexture?: WebGLTexture,
multiview?: boolean
): RenderTargetTexture {
if (!this._engine) {
throw new Error("Engine is disposed");
}
const textureSize = { width, height };
const renderTargetTexture = this._createRenderTargetTextureShell(width, height, !!multiview);
const renderTargetWrapper = renderTargetTexture.renderTarget as WebGLRenderTargetWrapper;
// Set the framebuffer, make sure it works in all scenarios - emulator, no layers and layers.
// This must happen before binding any texture, since setTexture binds it to the framebuffer.
if (framebuffer || !colorTexture) {
renderTargetWrapper._framebuffer = framebuffer;
}
// Create internal texture
if (colorTexture) {
if (multiview) {
renderTargetWrapper._colorTextureArray = colorTexture;
} else {
const internalTexture = this._createInternalTexture(textureSize, colorTexture);View on GitHub (pinned to 0592b347b8)
Solutions
- End the XR session and dispose XR providers before engine.dispose().
- Guard calls with a liveness check (`if (provider is alive)` / check engine not disposed) before fetching render target textures.
- Recreate the XR session manager, layers and texture providers after building a new engine.
- Defer/ignore render-target requests during teardown (e.g. null out frame callbacks first).
Example fix
// before engine.dispose(); const rtt = provider.getRenderTargetTextureForEye(eye); // throws // after const rtt = provider.getRenderTargetTextureForEye(eye); provider.dispose?.(); engine.dispose();
Defensive patterns
Strategy: try-catch
Validate before calling
if (!provider || provider._engine == null /* disposed */) {
return null; // engine disposed; cannot create RTT
} Type guard
function providerUsable(provider: WebXRWebGLRenderTargetTextureProvider): boolean {
// @ts-expect-error internal
return provider._engine != null;
} Try / catch
try {
const rtt = provider.getRenderTargetTextureForEye(eye);
} catch (e) {
if (e instanceof Error && e.message === 'Engine is disposed') {
console.warn('Skipping XR RTT fetch during engine teardown');
return null;
}
throw e;
} Prevention
- End the XR session and dispose providers before engine.dispose()
- Null out XR frame callbacks before teardown so late requests are avoided
- Rebuild XR providers when recreating an engine after context loss
- Guard render-target fetches with an engine-alive check
When it happens
Trigger: Requesting getRenderTargetTextureForEye(...) (or a layer RTT refresh) after engine.dispose(); an XR frame callback still running while the engine is being torn down; reusing a texture provider created with an old engine after engine recreation.
Common situations: Shutdown-order bug: engine.dispose() before ending the XR session; app teardown where XR compositor calls back into a disposed provider; swapping engines (context loss recovery) without rebuilding XR providers.
Related errors
- Cannot create the XR graphics binding: the engine has been d
- Restoring persistent anchors requires the anchor system to b
- Persistent anchor restoration was interrupted before trackin
- There is no NavMesh generated.
- There is no TileCache generated.
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/be1ac3215185cb4e.
Report an issue: GitHub.