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
- Before constructing, check axisOfRotation.Length != 0 and supply a valid non-zero axis.
- 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).
- If no rotation is desired, use the identity Quaternion (Quaternion.Identity) instead of constructing with a zero axis.
- 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
- Always check vector length before axis-angle construction
- Handle zero results from cross-product-derived axes (parallel vectors)
- Normalize computed axes before use
- Treat zero axis as 'no rotation' and use Quaternion.Identity
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
- SR.AddText_Invalid
- SR.Rect3D_CannotModifyEmptyRect
- SR.Size3D_DimensionCannotBeNegative
- " }} " element found. Expected fixed page element ( }} ).
- ' ' can only host a ' ' or a ' '. ' ' is an invalid…
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 MethodsView on GitHub (pinned to 81131a70a4)