dotnet/wpf · error · InvalidOperationException

SR.Quaternion_ZeroAxisSpecified

Error message

SR.Quaternion_ZeroAxisSpecified

What it means

The Quaternion(Vector3D axisOfRotation, double angleInDegrees) constructor builds a rotation quaternion from an axis-angle pair. If the axis vector has length 0 (Vector3D.Zero), there is no rotation axis, so the constructor throws InvalidOperationException with Quaternion_ZeroAxisSpecified.

Solutions

  1. Before constructing, check axisOfRotation.Length != 0 and supply a valid non-zero axis.
  2. If the axis is computed (e.g. from a cross product), handle the parallel/zero case explicitly and fall back to a default axis such as (0,1,0).
  3. If no rotation is desired, use the identity Quaternion (Quaternion.Identity) instead of constructing with a zero axis.
  4. Wrap the constructor in try/catch for InvalidOperationException when axis data comes from external input.

Example fix

// before
var q = new Quaternion(axis, angle); // throws if axis == (0,0,0)
// after
var q = axis.Length == 0 ? Quaternion.Identity : new Quaternion(axis, angle);
Defensive patterns

Strategy: validation

Validate before calling

if (axisOfRotation.Length == 0) { /* use Quaternion.Identity or fix axis */ }

Type guard

static bool IsValidRotationAxis(Vector3D axis) => axis.Length > 0;

Try / catch

try { var q = new Quaternion(axis, angleDegrees); }
catch (InvalidOperationException ex) when (ex.Message.Contains("axis"))
{
    var q = Quaternion.Identity; // degenerate axis: no rotation
}

Prevention

When it happens

Trigger: new Quaternion(new Vector3D(0,0,0), angle) or any axis vector whose X/Y/Z are all 0; also axes that degenerate to zero through computed expressions (e.g. cross product of parallel vectors) before being passed to the constructor.

Common situations: Computing an axis from a cross product of parallel vectors (result is zero); uninitialized Vector3D fields defaulting to (0,0,0); config/data producing a zero direction vector for rotations.

Understand the failure class

Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/390b47c5e9e64017. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media3D/Quaternion.cs:72

            _y = y;
            _z = z;
            _w = w;
            _isNotDistinguishedIdentity = true;
        }
        
        /// <summary>
        /// Constructs a quaternion via specified axis of rotation and an angle.
        /// Throws an InvalidOperationException if given (0,0,0) as axis vector.
        /// </summary>
        /// <param name="axisOfRotation">Vector representing axis of rotation.</param>
        /// <param name="angleInDegrees">Angle to turn around the given axis (in degrees).</param>
        public Quaternion(Vector3D axisOfRotation, double angleInDegrees)
        {
            angleInDegrees %= 360.0; // Doing the modulo before converting to radians reduces total error
            double angleInRadians = angleInDegrees * (Math.PI / 180.0);
            double length = axisOfRotation.Length;
            if (length == 0)
                throw new System.InvalidOperationException(SR.Quaternion_ZeroAxisSpecified);
            Vector3D v = (axisOfRotation / length) * Math.Sin(0.5 * angleInRadians);
            _x = v.X;
            _y = v.Y;
            _z = v.Z;
            _w = Math.Cos(0.5 * angleInRadians);
            _isNotDistinguishedIdentity = true;
        }

        #endregion Constructors

        
        //------------------------------------------------------
        //
        //  Public Methods
        //
        //------------------------------------------------------

        #region Public Methods

View on GitHub (pinned to 81131a70a4)