{"record":{"id":"bc6cb23faac7907c","repo":"dotnet/wpf","slug":"sr-matrixnotinvertible","errorCode":null,"errorMessage":"SR.MatrixNotInvertible","messagePattern":"SR\\.MatrixNotInvertible","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Ink/Stroke.cs","lineNumber":144,"sourceCode":"            clone._cloneStylusPoints = true;\n\n            return clone;\n        }\n\n\n        /// <summary>Transforms the ink and also changes the StylusTip</summary>\n        /// <param name=\"transformMatrix\">Matrix to transform the stroke by</param>\n        /// <param name=\"applyToStylusTip\">Boolean if true the transform matrix will be applied to StylusTip</param>\n        public virtual void Transform(Matrix transformMatrix, bool applyToStylusTip)\n        {\n            if (transformMatrix.IsIdentity)\n            {\n                return;\n            }\n\n            if (!transformMatrix.HasInverse)\n            {\n                throw new ArgumentException(SR.MatrixNotInvertible, nameof(transformMatrix));\n            }\n            else if ( MatrixHelper.ContainsNaN(transformMatrix))\n            {\n                throw new ArgumentException(SR.InvalidMatrixContainsNaN, nameof(transformMatrix));\n            }\n            else if ( MatrixHelper.ContainsInfinity(transformMatrix))\n            {\n                throw new ArgumentException(SR.InvalidMatrixContainsInfinity, nameof(transformMatrix));\n            }\n            else\n            {\n                // we need to force a recaculation of the cached path geometry right after the\n                // DrawingAttributes changed, beforet the events are raised.\n                _cachedGeometry = null;\n                // Set the cached bounds to empty, which will force a re-calculation of the _cachedBounds upon next GetBounds call.\n                _cachedBounds = Rect.Empty;\n\n                if (applyToStylusTip)","sourceCodeStart":126,"sourceCodeEnd":162,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Ink/Stroke.cs#L126-L162","documentation":"Stroke.Transform(Matrix) requires an invertible matrix so it can compute the inverse transform (needed to adjust things like stroke thickness when only stroke geometry is transformed). If matrix.HasInverse is false — i.e. the matrix is singular (zero determinant) — an ArgumentException naming transformMatrix is thrown and the stroke is left unchanged.","triggerScenarios":"Calling stroke.Transform(m) or InkCanvas/Strokes transforms with a singular Matrix, most typically new Matrix() (identity fields zeroed via SetIdentity misuse or default struct) or a scale/combined matrix with a zero scale factor (e.g. scaleX=0).","commonSituations":"Computing a transform from UI measurements where a dimension is 0 (width 0 element driving a scale); accumulating matrices leading to determinant 0; unit tests constructing Matrix via new Matrix() without SetIdentity.","solutions":["Check transformMatrix.HasInverse before calling Transform and pick a fallback matrix otherwise","Ensure scale factors are non-zero; fix the code that computed the matrix so determinant != 0","Call Matrix.Invert in a try/catch upstream to detect singular matrices early"],"exampleFix":"// before\nstroke.Transform(matrix); // throws when singular\n// after\nif (!matrix.HasInverse) { matrix = Matrix.Identity; }\nstroke.Transform(matrix);","handlingStrategy":"validation","validationCode":"if (!matrix.HasInverse) { matrix = Matrix.Identity; } stroke.Transform(matrix);","typeGuard":"bool IsUsableTransform(Matrix m) => m.HasInverse && !MatrixHelper.ContainsNaN(m) && !MatrixHelper.ContainsInfinity(m);","tryCatchPattern":"try { stroke.Transform(m); } catch (ArgumentException ex) { log(ex); m = Matrix.Identity; stroke.Transform(m); }","preventionTips":["Check Matrix.HasInverse before any Transform call","Build matrices with Matrix.CreateXX factory methods or SetIdentity, not new Matrix()","Validate scale factors are non-zero when composing transforms from UI dimensions"],"tags":["wpf","ink","matrix","argument-exception"],"backgroundTag":"invalid-argument-value","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-22T01:17:13.364Z"}