dotnet/wpf · error · ArgumentException

MatrixNotInvertible

Error message

MatrixNotInvertible

What it means

When StylusTipTransform is supplied as a Matrix, ExtendedPropertySerializer requires the matrix to be invertible (it maps the transform back and forth during serialization). A non-invertible matrix (zero determinant) throws ArgumentException with SR.MatrixNotInvertible.

Solutions

  1. Check Matrix.HasInverse before assigning and skip or substitute Identity when false
  2. Slightly adjust the scale factors so the determinant is non-zero
  3. Catch ArgumentException and fall back to Matrix.Identity

Example fix

// before
attrs[KnownIds.StylusTipTransform] = new Matrix(1, 0, 0, 0, 0, 0); // singular
// after
Matrix m = new Matrix(1, 0, 0, 1, 0, 0);
if (m.HasInverse) attrs[KnownIds.StylusTipTransform] = m;
Defensive patterns

Strategy: validation

Validate before calling

if (!matrix.HasInverse) matrix = Matrix.Identity;

Type guard

static bool IsUsableTransform(Matrix m) => m.HasInverse;

Try / catch

try { serializer.Serialize(...); }
catch (ArgumentException ex) when (ex.Message.Contains("invertible") || ex.Message.Contains("Matrix")) { props[KnownIds.StylusTipTransform] = Matrix.Identity; }

Prevention

When it happens

Trigger: Setting StylusTipTransform to a Matrix whose determinant is 0 — e.g. a matrix that scales an axis to 0 or projects onto a line — then serializing/validating extended properties.

Common situations: Building a Matrix from degenerate geometry (ScaleY=0, collapsed layout measurements producing zero scale); interpolating matrices that pass through a singular state.

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/671e270d02d84472. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/MS/internal/Ink/InkSerializedFormat/CustomAttributeSerializer.cs:829

                    throw new ArgumentException(SR.Format(SR.InvalidValueOfType, value, typeof(StylusTip)), nameof(value));
                }
            }
            else if (id == KnownIds.StylusTipTransform)
            {
                //
                // StylusTipTransform gets serialized as a String, but at runtime is a Matrix
                //
                Type t = value.GetType();
                if ( t != typeof(String) && t != typeof(Matrix) )
                {
                    throw new ArgumentException(SR.Format(SR.InvalidValueType1, typeof(String), typeof(Matrix)), nameof(value));
                }
                else if ( t == typeof(Matrix) )
                {
                    Matrix matrix = (Matrix)value;
                    if ( !matrix.HasInverse )
                    {
                        throw new ArgumentException(SR.MatrixNotInvertible, nameof(value));
                    }
                    if ( MatrixHelper.ContainsNaN(matrix))
                    {
                        throw new ArgumentException(SR.InvalidMatrixContainsNaN, nameof(value));
                    }
                    if ( MatrixHelper.ContainsInfinity(matrix))
                    {
                        throw new ArgumentException(SR.InvalidMatrixContainsInfinity, nameof(value));
                    }
}
            }
            else if (id == KnownIds.IsHighlighter)
            {
                if ( value.GetType() != typeof(bool))
                {
                    throw new ArgumentException(SR.Format(SR.InvalidValueType, typeof(bool)), nameof(value));
                }
            }

View on GitHub (pinned to 81131a70a4)