BabylonJS/Babylon.js · error · RangeError
XR view ${viewIndex} is not available in the current viewer
Error message
XR view ${viewIndex} is not available in the current viewer pose. What it means
After obtaining the viewer pose for the current frame, _getCurrentXRView checks that viewIndex is within pose.views.length. WebXR may return a pose with fewer views than expected (or no pose at all if the viewer pose is unavailable for this frame), so an out-of-range index throws a RangeError naming the requested view.
Source
Thrown at packages/dev/core/src/XR/webXRSessionManager.ts:294
}
private _getCurrentXRView(viewIndex: number): XRView {
if (!this.inXRSession || !this.session) {
throw new Error("Dynamic viewport scaling requires an active XR session.");
}
if (!this.inXRFrameLoop || !this.currentFrame) {
throw new Error("Dynamic viewport scaling must be used during an active XR frame.");
}
if (!this._referenceSpaceInitialized) {
throw new Error("Dynamic viewport scaling requires an initialized XR reference space.");
}
if (!Number.isInteger(viewIndex) || viewIndex < 0) {
throw new RangeError("The XR view index must be a non-negative integer.");
}
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) {
View on GitHub (pinned to 0592b347b8)
Solutions
- Query the actual view count per frame (pose.views.length via sessionManager or iterate available views) instead of hard-coding indices.
- Handle the case where the session is monoscopic: only request view(1) when a second view exists.
- Check that the session is still active and rendering before querying views; re-enter the render loop if it stopped.
- Fall back to the first view (index 0) or the default viewport when the requested index is unavailable.
Example fix
// before
scaleViewport(xr.view(1)); // assumes stereo
// after
const viewCount = xr.scene.activeCamera ? xr.getNumberOfViews?.() ?? 2 : 2;
if (viewCount > 1) {
scaleViewport(xr.view(1));
} else {
scaleViewport(xr.view(0));
} Defensive patterns
Strategy: fallback
Validate before calling
const pose = xr.currentFrame?.getViewerPose(xr.referenceSpace);
if (!pose || viewIndex >= pose.views.length) {
return; // view not available this frame
}
const v = xr.view(viewIndex); Type guard
function viewAvailable(xr: WebXRSessionManager, i: number): boolean {
const pose = xr.currentFrame?.getViewerPose(xr.referenceSpace);
return !!pose && i < pose.views.length;
} Try / catch
try {
const v = xr.view(1);
scaleViewport(v);
} catch (e) {
if (e instanceof RangeError && e.message.includes('not available')) {
scaleViewport(xr.view(0)); // monoscopic fallback
} else {
throw e;
}
} Prevention
- Never hard-code two views; query the view count per frame
- Handle monoscopic immersive-ar sessions (single view)
- Treat pose/views as per-frame data that can shrink or be null
- Fall back to view 0 / default viewport when the requested view is absent
When it happens
Trigger: Calling view(1) or view(2) when the session currently exposes only one view (e.g. a monoscopic/phone AR session); querying a view index right after entering/exiting a session where the pose is null; hardware configuration changes between frames.
Common situations: Hard-coding two eyes (view(0) and view(1)) but running in an immersive-ar mode that provides one view; getSession().renderState changes; a frame where getViewerPose returns null due to tracking loss or session pause.
Related errors
- Invalid Space Warp framebuffer
- WebGPUDurationMeasure: index out of range (" + index + ")
- Multiview is not supported
- XRCompositionLayer.${control} is not supported by this XR ru
- Anchors not enabled in this environment/browser
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/0c2b5d6635733149.
Report an issue: GitHub.