{"record":{"id":"dcbca462492f9d96","repo":"AvaloniaUI/Avalonia","slug":"transform-is-not-invertible","errorCode":null,"errorMessage":"Transform is not invertible.","messagePattern":"Transform is not invertible\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Avalonia.Base/Matrix.cs","lineNumber":490,"sourceCode":"                (_m21 * _m13 - _m11 * _m23) * invdet,\n                (_m21 * _m32 - _m31 * _m22) * invdet,\n                (_m31 * _m12 - _m11 * _m32) * invdet,\n                (_m11 * _m22 - _m21 * _m12) * invdet\n                );\n            \n            return true;\n        }\n\n        /// <summary>\n        /// Inverts the Matrix.\n        /// </summary>\n        /// <exception cref=\"InvalidOperationException\">Matrix is not invertible.</exception>\n        /// <returns>The inverted matrix.</returns>\n        public Matrix Invert()\n        {\n            if (!TryInvert(out var inverted))\n            {\n                throw new InvalidOperationException(\"Transform is not invertible.\");\n            }\n\n            return inverted;\n        }\n\n        /// <summary>\n        /// Parses a <see cref=\"Matrix\"/> string.\n        /// </summary>\n        /// <param name=\"s\">Six or nine comma-delimited double values (m11, m12, m21, m22, offsetX, offsetY[, perspX, perspY, perspZ]) that describe the new <see cref=\"Matrix\"/></param>\n        /// <returns>The <see cref=\"Matrix\"/>.</returns>\n        public static Matrix Parse(string s)\n        {\n            // initialize to satisfy compiler - only used when retrieved from string.\n            double v8 = 0;\n            double v9 = 0;\n\n            using (var tokenizer = new SpanStringTokenizer(s, CultureInfo.InvariantCulture, exceptionMessage: \"Invalid Matrix.\"))\n            {","sourceCodeStart":472,"sourceCodeEnd":508,"githubUrl":"https://github.com/AvaloniaUI/Avalonia/blob/11c542726898ae954a1ef668c65ec79ec92ab17d/src/Avalonia.Base/Matrix.cs#L472-L508","documentation":"Matrix.Invert throws when the matrix is singular (determinant is zero or near-zero), meaning it has no inverse. Matrix transforms map points; a non-invertible matrix collapses space (e.g. a zero-scale transform) and cannot reverse-map points. Use TryInvert for a non-throwing variant.","triggerScenarios":"Calling matrix.Invert() on a matrix with determinant 0 — typically a scale of (0, anything) or (anything, 0), or any transform that collapses a dimension. Also from rendering code that needs to invert a transform for hit-testing.","commonSituations":"Setting a ScaleTransform with scale 0. A composite transform that mathematically collapses. Animating a scale property through 0. Hit-testing code inverting a degenerate transform.","solutions":["Use matrix.TryInvert(out var inv) instead of Invert() and handle the false case gracefully.","Ensure scale transforms never reach exactly 0 on a collapsed axis — clamp to a small epsilon.","Check matrix.HasInverse before calling Invert() if available, or compute the determinant."],"exampleFix":"// before\nvar inv = transform.Value.Invert();\n\n// after\nif (transform.Value.TryInvert(out var inv))\n{\n    // use inv\n}\nelse\n{\n    // handle non-invertible case (e.g. skip hit test)\n}","handlingStrategy":"validation","validationCode":"if (matrix.TryInvert(out var inv))\n{\n    // use inv\n}\nelse\n{\n    // matrix is singular; skip invert-dependent logic\n}","typeGuard":null,"tryCatchPattern":"Matrix inv;\ntry { inv = matrix.Invert(); }\ncatch (InvalidOperationException)\n{\n    // handle non-invertible: skip hit-test or use identity\n    inv = Matrix.Identity;\n}","preventionTips":["Prefer TryInvert over Invert for any transform that could be degenerate.","Clamp scale transforms away from exactly 0.","Guard hit-testing code that inverts transforms against singular matrices."],"tags":["matrix","transform","math","invertible","rendering"],"backgroundTag":null,"analyzedSha":"11c542726898ae954a1ef668c65ec79ec92ab17d","analyzedAt":"2026-08-13T11:57:40.261Z","schemaVersion":2},"datasetVersion":"2026-08-13T14:17:21.547Z"}