dotnet/wpf · error · InvalidOperationException

SR.GeneralTransform_TransformFailed

Error message

SR.GeneralTransform_TransformFailed

What it means

GeneralTransform.Transform(Point) throws InvalidOperationException wrapping SR.GeneralTransform_TransformFailed when TryTransform returns false, i.e., the transform could not map the point (typically because the visual is not connected to a presentation source or the transform is degenerate/non-invertible). Unlike TryTransform, Transform treats failure as an exception rather than returning false.

Solutions

  1. Prefer TryTransform and handle the false return instead of letting Transform throw.
  2. Defer the transform until the visual is loaded (handle the Loaded event or check IsLoaded) so coordinates are valid.
  3. Verify the transform matrix is invertible (no zero scale) before transforming.
  4. Use PointToScreen/PointFromScreen alternatives if the visual is disconnected from the presentation source.

Example fix

// before
var pt = generalTransform.Transform(anchorPoint);

// after
if (generalTransform.TryTransform(anchorPoint, out var pt))
{
    // use pt
}
else
{
    pt = anchorPoint; // fallback
}
Defensive patterns

Strategy: try-catch

Validate before calling

bool canTransform = visual.IsLoaded && generalTransform != null && !generalTransform.Value.HasInverse == false; // prefer TryTransform
if (!generalTransform.TryTransform(point, out _)) { /* skip or defer */ }

Type guard

bool IsTransformable(Visual v) => v != null && v.IsLoaded;

Try / catch

try
{
    transformed = generalTransform.Transform(point);
}
catch (InvalidOperationException)
{
    // visual not ready or singular transform
    transformed = point; // or defer until Loaded
}

Prevention

When it happens

Trigger: Calling Transform, TransformToAncestor, or TransformToDescendant on a Visual whose transform matrix is singular (zero scale) or whose coordinates cannot be computed because the visual has no valid layout/presentation source yet.

Common situations: Hit-testing or positioning popups/context menus before the element is loaded and rendered (IsLoaded == false); transforms involving a ScaleTransform with scale 0; adorner coordinate math (pointOnSelectionAdorner, pointOnInnerCanvas) running too early in the visual tree lifecycle.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/18e3553a6a77b784. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/GeneralTransform.cs:46

        /// <summary>
        /// Transform a point
        /// 
        /// If the transformation does not succeed, this will throw an InvalidOperationException.
        /// If you don't want to try/catch, call TryTransform instead and check the boolean it
        /// returns.
        ///
        /// Note that this method will always succeed when called on a subclass of Transform
        /// </summary>
        /// <param name="point">Input point</param>
        /// <returns>The transformed point</returns>
        public Point Transform(Point point)
        {
            Point transformedPoint;

            if (!TryTransform(point, out transformedPoint))
            {
                throw new InvalidOperationException(SR.Format(SR.GeneralTransform_TransformFailed, null));
            }

            return transformedPoint;
        }
        
        /// <summary>
        /// Transforms the bounding box to the smallest axis aligned bounding box
        /// that contains all the points in the original bounding box
        /// </summary>
        /// <param name="rect">Bounding box</param>
        /// <returns>The transformed bounding box</returns>
        public abstract Rect TransformBounds(Rect rect);


        /// <summary>
        /// Returns the inverse transform if it has an inverse, null otherwise
        /// </summary>        
        public abstract GeneralTransform Inverse { get; }

View on GitHub (pinned to 81131a70a4)