dotnet/wpf · error · InvalidOperationException

SR.Transform_NotInvertible

Error message

SR.Transform_NotInvertible

What it means

Matrix.Invert() throws InvalidOperationException(SR.Transform_NotInvertible) when the matrix determinant is zero (or numerically zero), meaning the matrix is singular and has no inverse. A non-invertible matrix collapses space (e.g. a scale of 0 on an axis), so inversion is mathematically impossible.

Solutions

  1. Check Math.Abs(matrix.Determinant) > epsilon before calling Invert().
  2. Guard against zero scale/width/height values feeding into the matrix.
  3. Use Matrix.HasInverse (or TryInvert where available) to test invertibility first.
  4. Catch InvalidOperationException and substitute an identity matrix or skip the inverse operation.

Example fix

// before
matrix.Invert(); // throws when singular
// after
if (matrix.HasInverse)
    matrix.Invert();
else
    matrix = Matrix.Identity;
Defensive patterns

Strategy: validation

Validate before calling

bool invertible = matrix.HasInverse; // or Math.Abs(matrix.Determinant) > 1e-12

Type guard

static bool IsInvertible(System.Windows.Media.Matrix m) => m.HasInverse;

Try / catch

try { matrix.Invert(); }
catch (InvalidOperationException) { matrix = Matrix.Identity; }

Prevention

When it happens

Trigger: Calling Invert() on a matrix with Determinant == 0, e.g. a scale transform with a 0 scale factor, a projection onto a line, or a matrix built from degenerate control points.

Common situations: Animating scale to/from 0 and inverting mid-animation; computing inverse transforms for hit-testing with degenerate geometry; user-configurable transforms set to zero-width/height; float round-off producing an exactly-zero determinant.

Understand the failure class

Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Media/Matrix.cs:433

            {
                return !DoubleUtil.IsZero(Determinant);
            }
        }

        /// <summary>
        /// Replaces matrix with the inverse of the transformation.  This will throw an InvalidOperationException
        /// if !HasInverse
        /// </summary>
        /// <exception cref="InvalidOperationException">
        /// This will throw an InvalidOperationException if the matrix is non-invertable
        /// </exception>
        public void Invert()
        {
            double determinant = Determinant;

            if (DoubleUtil.IsZero(determinant))
            {
                throw new System.InvalidOperationException(SR.Transform_NotInvertible);
            }

            // Inversion does not change the type of a matrix.
            switch (_type)
            {
            case MatrixTypes.TRANSFORM_IS_IDENTITY:
                break;
            case MatrixTypes.TRANSFORM_IS_SCALING:
                {
                    _m11 = 1.0 / _m11;
                    _m22 = 1.0 / _m22;
                }
                break;
            case MatrixTypes.TRANSFORM_IS_TRANSLATION:
                _offsetX = -_offsetX;
                _offsetY = -_offsetY;
                break;
            case MatrixTypes.TRANSFORM_IS_SCALING | MatrixTypes.TRANSFORM_IS_TRANSLATION:

View on GitHub (pinned to 81131a70a4)