{"record":{"id":"175479132daed28c","repo":"SixLabors/ImageSharp","slug":"matrix-is-degenerate-check-input-values-175479","errorCode":null,"errorMessage":"Matrix is degenerate. Check input values.","messagePattern":"Matrix is degenerate\\. Check input values\\.","errorType":"exception","errorClass":"DegenerateTransformException","httpStatus":null,"severity":"error","filePath":"src/ImageSharp/Processing/Processors/Transforms/Linear/AffineTransformProcessor.cs","lineNumber":26,"sourceCode":"/// <summary>\n/// Defines an affine transformation applicable on an <see cref=\"Image\"/>.\n/// </summary>\npublic class AffineTransformProcessor : CloningImageProcessor\n{\n    /// <summary>\n    /// Initializes a new instance of the <see cref=\"AffineTransformProcessor\"/> class.\n    /// </summary>\n    /// <param name=\"matrix\">The transform matrix.</param>\n    /// <param name=\"sampler\">The sampler to perform the transform operation.</param>\n    /// <param name=\"targetDimensions\">The target dimensions.</param>\n    public AffineTransformProcessor(Matrix3x2 matrix, IResampler sampler, Size targetDimensions)\n    {\n        Guard.NotNull(sampler, nameof(sampler));\n        Guard.MustBeValueType(sampler);\n\n        if (TransformUtilities.IsDegenerate(matrix))\n        {\n            throw new DegenerateTransformException(\"Matrix is degenerate. Check input values.\");\n        }\n\n        this.Sampler = sampler;\n        this.TransformMatrix = matrix;\n        this.DestinationSize = targetDimensions;\n    }\n\n    /// <summary>\n    /// Gets the sampler to perform interpolation of the transform operation.\n    /// </summary>\n    public IResampler Sampler { get; }\n\n    /// <summary>\n    /// Gets the matrix used to supply the affine transform.\n    /// </summary>\n    public Matrix3x2 TransformMatrix { get; }\n\n    /// <summary>","sourceCodeStart":8,"sourceCodeEnd":44,"githubUrl":"https://github.com/SixLabors/ImageSharp/blob/59ce6af6fc29027cda277ef62d4d1694a8acce91/src/ImageSharp/Processing/Processors/Transforms/Linear/AffineTransformProcessor.cs#L8-L44","documentation":"The AffineTransformProcessor constructor validates that the affine transform matrix is not degenerate — i.e. it collapses space (zero determinant / non-invertible), so no meaningful source-to-destination mapping exists. TransformUtilities.IsDegenerate performs this check and DegenerateTransformException is thrown before any pixels are processed.","triggerScenarios":"Creating an AffineTransformProcessor (or calling AffineTransformBuilder-driven Mutate/Transform overloads) with a matrix whose determinant is zero, e.g. a scale of 0 on an axis or a projection onto a line.","commonSituations":"Building transform matrices from user input or configuration where a scale factor is 0; concatenating matrices that cancel each other out; computing matrices at runtime (from fit-to-size math) that produce a singular result.","solutions":["Check the matrix before passing it: ensure it has a non-zero determinant (Matrix4x4.GetDeterminant() != 0)","Fix the source of the matrix — e.g. clamp scale factors away from 0","Catch DegenerateTransformException and fall back to an identity or last-known-good transform","Validate concatenated matrices after each append/prepend when building transforms dynamically"],"exampleFix":"// before\nvar matrix = Matrix3x2.CreateScale(scaleX, scaleY); // scaleX == 0 from config\nimage.Mutate(x => x.Transform(matrix));\n// after\nif (Math.Abs(Matrix3x2.CreateScale(scaleX, scaleY).GetDeterminant()) < float.Epsilon)\n{\n    throw new InvalidOperationException(\"Affine matrix is degenerate; check scale factors.\");\n}\nimage.Mutate(x => x.Transform(Matrix3x2.CreateScale(scaleX, scaleY)));","handlingStrategy":"validation","validationCode":"static bool IsNonDegenerate(Matrix4x4 m) => MathF.Abs(m.GetDeterminant()) > 1e-6f;\nif (!IsNonDegenerate(matrix)) throw new InvalidOperationException(\"Affine matrix is degenerate.\");","typeGuard":"static bool IsUsableAffineTransform(Matrix4x4 m) => !float.IsNaN(m.GetDeterminant()) && MathF.Abs(m.GetDeterminant()) > float.Epsilon;","tryCatchPattern":"try\n{\n    image.Mutate(x => x.Transform(affineMatrix));\n}\ncatch (DegenerateTransformException ex)\n{\n    // fall back to identity or last known good matrix\n    throw;\n}","preventionTips":["Validate scale factors are non-zero before composing scale transforms","Check determinant after every matrix concatenation","Avoid hard-coded matrices; derive them from helpers (CreateScale/CreateRotation/Skew) with clamped inputs","Add unit tests for each transform source with realistic configuration values"],"tags":["affine-transform","matrix","validation"],"backgroundTag":"invalid-argument-value","analyzedSha":"59ce6af6fc29027cda277ef62d4d1694a8acce91","analyzedAt":"2026-09-13T18:34:59.331Z","contentChangedAt":"2026-09-13T18:34:59.331Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}