{"record":{"id":"b6c3aa2f1f557382","repo":"dotnet/wpf","slug":"sr-stylus-matrixnotinvertable","errorCode":null,"errorMessage":"SR.Stylus_MatrixNotInvertable","messagePattern":"SR\\.Stylus_MatrixNotInvertable","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Common/RawStylusInput.cs","lineNumber":29,"sourceCode":"    /// </summary>\n    public class RawStylusInput\n    {\n        /////////////////////////////////////////////////////////////////////\n        /// <summary>\n        ///     [TBS]\n        /// </summary>\n        /// <param name=\"report\">[TBS]</param>\n        /// <param name=\"tabletToElementTransform\">[TBS]</param>\n        /// <param name=\"targetPlugInCollection\">[TBS]</param>\n        internal RawStylusInput(\n            RawStylusInputReport    report,\n            GeneralTransform        tabletToElementTransform,\n            StylusPlugInCollection targetPlugInCollection)\n        {\n            ArgumentNullException.ThrowIfNull(report);\n            if (tabletToElementTransform.Inverse == null)\n            {\n                throw new ArgumentException(SR.Stylus_MatrixNotInvertable, nameof(tabletToElementTransform));\n            }\n            ArgumentNullException.ThrowIfNull(targetPlugInCollection);\n\n            // We should always see this GeneralTransform is frozen since we access this from multiple threads.\n            System.Diagnostics.Debug.Assert(tabletToElementTransform.IsFrozen);\n            _report                 = report;\n            _tabletToElementTransform  = tabletToElementTransform;\n            _targetPlugInCollection = targetPlugInCollection;\n        }\n\n        /// <summary>\n        /// \n        /// </summary>\n        public int StylusDeviceId { get { return _report.StylusDeviceId; } }    \n\n        /// <summary>\n        /// \n        /// </summary>","sourceCodeStart":11,"sourceCodeEnd":47,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Input/Stylus/Common/RawStylusInput.cs#L11-L47","documentation":"The RawStylusInput constructor requires a tabletToElementTransform that can be inverted, because stylus sample points must be mapped from tablet coordinates into element coordinates (and the transform is accessed from multiple threads, hence also required frozen). Passing a transform whose Inverse is null (a non-invertible matrix, e.g. zero-scale) throws ArgumentException with SR.Stylus_MatrixNotInvertable.","triggerScenarios":"Constructing RawStylusInput with a GeneralTransform whose underlying Matrix is non-invertible — typically a scale of 0 on an axis, a collapsed layout (Width/Height = 0 producing a degenerate matrix), or a custom transform failing to produce an inverse.","commonSituations":"Stylus plug-in code computing the transform from an element with zero width/height or an AnimationClock holding scale at 0; a collapsed Visibility element inside a stylus plug-in pipeline; custom GeneralTransform implementations returning null Inverse.","solutions":["Check tabletToElementTransform.Inverse != null before constructing RawStylusInput and bail or substitute an identity transform.","Avoid degenerate element layouts: ensure the target element has non-zero width/height (no collapsed dimensions) when computing the transform.","Freeze the GeneralTransform before use, as the constructor also asserts IsFrozen for cross-thread access.","If scale animation can reach 0, clamp it (e.g. Math.Max(0.001, scale)) before building the matrix."],"exampleFix":"// before\nvar input = new RawStylusInput(report, tabletToElement, pluginCollection); // throws if not invertible\n\n// after\nif (tabletToElement.Inverse == null)\n    tabletToElement = Transform.Identity;\nif (!tabletToElement.IsFrozen)\n    tabletToElement.Freeze();\nvar input = new RawStylusInput(report, tabletToElement, pluginCollection);","handlingStrategy":"validation","validationCode":"if (tabletToElementTransform?.Inverse == null)\n    tabletToElementTransform = Transform.Identity;\nif (tabletToElementTransform.CanFreeze && !tabletToElementTransform.IsFrozen)\n    tabletToElementTransform.Freeze();","typeGuard":"static bool IsUsableTabletTransform(GeneralTransform t) =>\n    t != null && t.Inverse != null && t.IsFrozen;","tryCatchPattern":"try\n{\n    var input = new RawStylusInput(report, tabletToElement, pluginCollection);\n}\ncatch (ArgumentException ex) when (ex.ParamName == nameof(tabletToElementTransform))\n{\n    // non-invertible transform: fall back to identity or skip this frame\n}","preventionTips":["Always check Inverse != null before constructing RawStylusInput.","Avoid degenerate layouts: don't attach plug-ins to elements with zero width/height.","Freeze transforms before passing them in (the constructor asserts IsFrozen).","Clamp scale animations so they never reach exactly 0."],"tags":["wpf","stylus","matrix","argument-validation"],"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-21T21:30:21.729Z"}