BabylonJS/Babylon.js · error · ReferenceError

Can not fract a quaternion

Error message

Can not fract a quaternion

What it means

Quaternion.fract() is a deliberate stub that exists only so Quaternion conforms to the shared vector-like interface; computing fractional parts of quaternion components has no mathematical meaning. It is marked @internal 'Do not use' and unconditionally throws ReferenceError('Can not fract a quaternion'). A runtime call means a component-wise operation was applied to a quaternion incorrectly.

Source

Thrown at packages/dev/core/src/Maths/math.vector.pure.ts:5091

     */
    public floor(): Quaternion {
        throw new ReferenceError("Can not floor a quaternion");
    }

    /**
     * @internal
     * Do not use
     */
    public fractToRef<T extends Quaternion>(_result: T): T {
        throw new ReferenceError("Can not fract a quaternion");
    }

    /**
     * @internal
     * Do not use
     */
    public fract(): Quaternion {
        throw new ReferenceError("Can not fract a quaternion");
    }

    /**
     * Conjugates the current quaternion and stores the result in the given quaternion
     * Example Playground https://playground.babylonjs.com/#L49EJ7#81
     * @param ref defines the target quaternion
     * @returns result input
     */
    public conjugateToRef<T extends Quaternion>(ref: T): T {
        ref.copyFromFloats(-this._x, -this._y, -this._z, this._w);
        return ref;
    }

    /**
     * Conjugates in place the current quaternion
     * Example Playground https://playground.babylonjs.com/#L49EJ7#82
     * @returns the current updated quaternion
     */

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Do not call fract() on Quaternion; if needed, compute x - Math.floor(x) etc. on components manually.
  2. Ensure rotation values go through quaternion-specific APIs (slerp, normalize, conjugate) rather than component-wise vector ops.
  3. In generic pipelines, check the concrete type and dispatch to quaternion-safe operations.

Example fix

// before
q.fract();

// after
const result = new BABYLON.Quaternion(
  q.x - Math.floor(q.x),
  q.y - Math.floor(q.y),
  q.z - Math.floor(q.z),
  q.w - Math.floor(q.w)
);
Defensive patterns

Strategy: type-guard

Validate before calling

if (q instanceof BABYLON.Quaternion) {
  throw new TypeError('fract() is not supported on Quaternion; use quaternion-specific APIs');
}

Type guard

function isVectorLikeNotQuaternion(v) {
  return v instanceof BABYLON.Vector3 || v instanceof BABYLON.Vector4;
}

Try / catch

try {
  q.fract();
} catch (e) {
  if (e instanceof ReferenceError && e.message === 'Can not fract a quaternion') {
    const r = new BABYLON.Quaternion(q.x - Math.floor(q.x), q.y - Math.floor(q.y), q.z - Math.floor(q.z), q.w - Math.floor(q.w));
  } else {
    throw e;
  }
}

Prevention

When it happens

Trigger: Calling quaternionInstance.fract() on a Quaternion (packages/dev/core/src/Maths/math.vector.pure.ts:5091). Generic code written for Vector3/Vector4 (where fract is valid) called with a Quaternion instance.

Common situations: Interpolation/tiling math that calls fract generically on 'vector-like' rotation values; shader-translation helpers mapping GLSL fract() over uniform math types; code mixing rotations and positions in shared pipelines.

Related errors


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