BabylonJS/Babylon.js · error

XRCompositionLayer.${control} is not supported by this XR ru

Error message

XRCompositionLayer.${control} is not supported by this XR runtime.

What it means

WebXRCompositionLayer wraps a native XRCompositionLayer and allows controlling opacity, quality, and forceMonoPresentation. These controls only exist if the underlying XRCompositionLayer object actually exposes the corresponding property. The helper _assertControlSupported checks `control in this.layer` and throws when the active XR runtime's native layer lacks that capability.

Source

Thrown at packages/dev/core/src/XR/features/Layers/WebXRCompositionLayer.ts:144

        public override readonly layerType: LayerTypeT,
        /**
         * Whether the layer renders both views into a texture array.
         */
        public readonly isMultiview: boolean,
        public createRTTProvider: (xrSessionManager: WebXRSessionManager) => WebXRLayerRenderTargetTextureProvider<LayerTypeT>,
        public _originalInternalTexture: Nullable<InternalTexture> = null,
        private readonly _destroyLayerOnDispose = false,
        /**
         * Whether the layer can only be rendered when its native `needsRedraw` flag is set.
         */
        public readonly isStatic = false
    ) {
        super(getWidth, getHeight, layer, layerType, createRTTProvider);
    }

    private _assertControlSupported(control: "opacity" | "quality" | "forceMonoPresentation"): void {
        if (!(control in this.layer)) {
            throw new Error(`XRCompositionLayer.${control} is not supported by this XR runtime.`);
        }
    }

    /**
     * Disposes the Babylon render-target resources and destroys the native layer when this wrapper owns it.
     */
    public override dispose(): void {
        super.dispose();
        if (this._destroyLayerOnDispose) {
            this.layer.destroy();
        }
    }
}

/**
 * Wraps a positionable XR composition layer and synchronizes it with a Babylon transform node.
 * The node's scaling does not affect the physical dimensions of the layer.
 * @typeParam LayerT the concrete positionable WebXR layer type

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Check `control in nativeLayer` (e.g. 'opacity' in layer.layer) before setting the property
  2. Feature-detect once after layer creation and gate UI code that exposes these controls
  3. Update the browser/XR runtime to a version implementing the full XRCompositionLayer API
  4. Catch the error and skip the control silently when the runtime lacks support

Example fix

// before
compositionLayer.opacity = 0.5;
// after
if ('opacity' in compositionLayer.layer) {
  compositionLayer.opacity = 0.5;
} else {
  console.warn('opacity not supported by this XR runtime');
}
Defensive patterns

Strategy: type-guard

Validate before calling

const supports = (layer: WebXRCompositionLayer, c: 'opacity'|'quality'|'forceMonoPresentation') => c in layer.layer;

Type guard

function supportsControl(layer: XRCompositionLayer, control: string): boolean {
  return control in layer;
}

Try / catch

try {
  compositionLayer.opacity = 0.5;
} catch {
  console.warn('XRCompositionLayer control unsupported; skipping');
}

Prevention

When it happens

Trigger: Setting opacity, quality, or forceMonoPresentation on a WebXRCompositionLayer whose underlying native XRCompositionLayer (from the XR runtime, e.g. some WebXR implementations or emulators) does not implement the corresponding property on the native object.

Common situations: Running on a browser/device whose WebXR composition layer support is partial (property missing from the spec implementation), using an emulator or polyfill that creates layers without these members, assuming desktop Chrome behavior applies to mobile/headset runtimes.

Related errors


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/e12e3fad3b96e5d3. Report an issue: GitHub.