{"record":{"id":"497eea1eb7fd805b","repo":"BabylonJS/Babylon.js","slug":"webxrwebglrendertargettextureprovider-requires-a-w","errorCode":null,"errorMessage":"WebXRWebGLRenderTargetTextureProvider requires a WebGL-capable engine.","messagePattern":"WebXRWebGLRenderTargetTextureProvider requires a WebGL-capable engine\\.","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"packages/dev/core/src/XR/webXRWebGLRenderTargetTextureProvider.ts","lineNumber":19,"sourceCode":"import { type ThinEngine } from \"../Engines/thinEngine\";\nimport { WebGLHardwareTexture } from \"../Engines/WebGL/webGLHardwareTexture\";\nimport { type WebGLRenderTargetWrapper } from \"../Engines/WebGL/webGLRenderTargetWrapper\";\nimport { InternalTexture, InternalTextureSource } from \"../Materials/Textures/internalTexture\";\nimport { type RenderTargetTexture } from \"../Materials/Textures/renderTargetTexture.pure\";\nimport { type Nullable } from \"../types\";\nimport { WebXRLayerRenderTargetTextureProvider } from \"./webXRRenderTargetTextureProvider\";\nimport { type WebXRLayerType, type WebXRSupportedLayerType } from \"./webXRLayerWrapper\";\n\n/**\n * Provides render target textures for WebGL-backed XR layers. Owns all WebGL-specific\n * framebuffer/texture wiring so the base provider can stay graphics-API-agnostic.\n * @internal\n */\nexport abstract class WebXRWebGLRenderTargetTextureProvider<LayerTypeT extends WebXRSupportedLayerType = WebXRLayerType> extends WebXRLayerRenderTargetTextureProvider<LayerTypeT> {\n    private _createInternalTexture(textureSize: { width: number; height: number }, texture: WebGLTexture): InternalTexture {\n        const gl = (this._engine as ThinEngine)._gl;\n        if (!gl) {\n            throw new Error(\"WebXRWebGLRenderTargetTextureProvider requires a WebGL-capable engine.\");\n        }\n        const internalTexture = new InternalTexture(this._engine, InternalTextureSource.Unknown, true);\n        internalTexture.width = textureSize.width;\n        internalTexture.height = textureSize.height;\n        internalTexture._hardwareTexture = new WebGLHardwareTexture(texture, gl);\n        internalTexture.isReady = true;\n        return internalTexture;\n    }\n\n    protected _createRenderTargetTexture(\n        width: number,\n        height: number,\n        framebuffer: Nullable<WebGLFramebuffer>,\n        colorTexture?: WebGLTexture,\n        depthStencilTexture?: WebGLTexture,\n        multiview?: boolean\n    ): RenderTargetTexture {\n        if (!this._engine) {","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/BabylonJS/Babylon.js/blob/0592b347b8a4ee0236089ea86a749cacfdb266d8/packages/dev/core/src/XR/webXRWebGLRenderTargetTextureProvider.ts#L1-L37","documentation":"_createInternalTexture wraps a raw WebGLTexture handed over by the XR compositor into a Babylon InternalTexture. It casts the engine to ThinEngine and reads its WebGL context (_gl). If the engine has no GL context (e.g. a WebGPU engine or an engine whose context was lost/disposed), the wrapping cannot proceed and this error is thrown.","triggerScenarios":"Using a WebXR render target texture provider (WebXRWebGLRenderTargetTextureProvider._createRenderTargetTexture / internalTexture) with a WebGPU engine or an engine where _gl is null (context lost, engine disposed, NullEngine).","commonSituations":"Mixing WebGPU engine with a WebGL-only XR session (requestSession without gl context / wrong graphics binding type); running XR in a NullEngine test environment; engine context loss during an active XR session.","solutions":["Create the app engine as a WebGL ThinEngine when using WebGL-based XR sessions (matching WebXRWebGLGraphicsBinding), not WebGPU.","Use the WebGPU-specific XR path/binding (WebXRWebGPUGraphicsBinding and its texture provider) when the engine is WebGPU.","Check `engine.isWebGL` / `(engine as ThinEngine)._gl` before setting up XR render target textures and choose the right provider.","Recreate the WebGL context / engine if it was lost, then restart the XR session before requesting render target textures."],"exampleFix":"// before\nconst engine = new WebGPUEngine(canvas); // but using WebGL XR session layer\nconst xrRTT = new WebXRWebGLRenderTargetTextureProvider(engine, xr); // throws\n// after\nconst engine = new Engine(canvas, true); // WebGL engine for WebGL XR session\nconst xrRTT = new WebXRWebGLRenderTargetTextureProvider(engine, xr);","handlingStrategy":"type-guard","validationCode":"import { ThinEngine } from '@babylonjs/core/Engines/thinEngine';\nconst gl = (engine as ThinEngine)._gl;\nif (!gl) {\n  throw new Error('Cannot set up WebGL XR render targets: no WebGL context');\n}","typeGuard":"function isWebGLEngine(engine: AbstractEngine): engine is ThinEngine {\n  return !engine.isWebGPU && !!(engine as ThinEngine)._gl;\n}","tryCatchPattern":"try {\n  const rtt = provider.getRenderTargetTextureForEye(eye);\n} catch (e) {\n  if (e instanceof Error && e.message.includes('WebGL-capable engine')) {\n    console.error('Wrong engine type for WebGL XR session:', e.message);\n    return null;\n  }\n  throw e;\n}","preventionTips":["Pair a WebGL engine with WebGL XR sessions and WebGPU engine with WebGPU XR paths","Don't use NullEngine/disposed engines for XR render target providers","Check engine.isWebGL / _gl before creating XR texture providers","Handle context-loss events by rebuilding the XR pipeline, not reusing providers"],"tags":["webxr","webgl","engine-mismatch"],"backgroundTag":"webgl-context-unavailable","analyzedSha":"0592b347b8a4ee0236089ea86a749cacfdb266d8","analyzedAt":"2026-08-30T15:11:20.442Z","schemaVersion":2},"datasetVersion":"2026-08-30T18:17:15.746Z"}