BabylonJS/Babylon.js · error
Cannot create the XR graphics binding before the XR session
Error message
Cannot create the XR graphics binding before the XR session is initialized.
What it means
The XR graphics binding must be created with a live XRSession (WebGL/WebGPU binding constructors take the session). _getGraphicsBinding throws if this.session is null, i.e. the manager has no initialized session yet — the binding cannot exist before a session does.
Source
Thrown at packages/dev/core/src/XR/webXRSessionManager.ts:310
const pose = this.currentFrame.getViewerPose(this.referenceSpace);
if (!pose || viewIndex >= pose.views.length) {
throw new RangeError(`XR view ${viewIndex} is not available in the current viewer pose.`);
}
return pose.views[viewIndex];
}
/**
* Obtains the XR graphics binding for the current session, creating it lazily.
* This is the API-agnostic seam used by WebGL and WebGPU XR features to share a binding.
* @returns the XR graphics binding for the current session
* @internal
*/
public _getGraphicsBinding(): WebXRGraphicsBinding {
if (!this._engine) {
throw new Error("Cannot create the XR graphics binding: the engine has been disposed.");
}
if (!this.session) {
throw new Error("Cannot create the XR graphics binding before the XR session is initialized.");
}
if (!this._graphicsBinding) {
this._graphicsBinding = this._engine.isWebGPU
? WebXRWebGPUGraphicsBinding.CreateFromEngine(this.session, this._engine)
: WebXRWebGLGraphicsBinding.CreateFromEngine(this.session, this._engine);
}
return this._graphicsBinding;
}
/**
* Creates a WebXRRenderTarget object for the XR session
* @param options optional options to provide when creating a new render target
* @returns a WebXR render target to which the session can render
*/
public getWebXRRenderTarget(options?: WebXRManagedOutputCanvasOptions): WebXRRenderTarget {
const engine = this.scene.getEngine();
if (this._xrNavigator.xr.native) {
return new NativeXRRenderTarget(this);
View on GitHub (pinned to 0592b347b8)
Solutions
- Start the session first (await xr.initializeAsync(); await xr.setSessionAsync(...) or Helper.createDefaultSessionAsync) before any code that touches graphics bindings.
- Check `xr.sessionManager.session != null` before creating layers/features that need the binding.
- Initialize features after the session is ready — use onXRSessionInit / session observables rather than constructor-time setup.
- Create a fresh session manager per session instead of reusing one whose session ended.
Example fix
// before
const xr = new WebXRSessionManager(scene);
const provider = new WebXRWebGLRenderTargetTextureProvider(engine, xr.sessionManager); // no session yet
// after
const xr = new WebXRSessionManager(scene);
await xr.setSessionAsync(await navigator.xr.requestSession('immersive-vr'));
const provider = new WebXRWebGLRenderTargetTextureProvider(engine, xr.sessionManager); Defensive patterns
Strategy: validation
Validate before calling
if (!xr.session) {
throw new Error('XR session must be started before creating graphics bindings');
}
const binding = xr._getGraphicsBinding(); Type guard
function sessionActive(xr: WebXRSessionManager): xr is WebXRSessionManager & { session: XRSession } {
return xr.session != null;
} Try / catch
try {
const binding = xr._getGraphicsBinding();
} catch (e) {
if (e instanceof Error && e.message.includes('before the XR session')) {
console.warn('Graphics binding requested before session start — deferring');
return null;
}
throw e;
} Prevention
- Await initializeAsync + setSessionAsync before any layer/feature setup
- Check sessionManager.session before building composition layers
- Initialize WebXR features from session-start observables, not constructors
- Create a new manager per session; do not reuse managers whose session ended
When it happens
Trigger: Calling _getGraphicsBinding() (or a layer/feature that requests it) after creating the WebXRSessionManager but before initializeAsync/setSession established a session; using a manager whose session ended and was cleared; attempting to register a WebXR layer manually without starting a session first.
Common situations: Instantiating WebXRLayerRenderTargetTextureProvider or custom composition layers at setup time instead of after session start; a feature's attach() running before the session promise resolved; reusing a session manager object after session end for a new attempt.
Related errors
- Dynamic viewport scaling requires an initialized XR referenc
- Recast is not initialized. Please call InitRecast first.
- There is no NavMesh generated.
- Function not injected yet. Use the factory to create the plu
- There is no navMesh generated.
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/c8b286b7fb251b38.
Report an issue: GitHub.