dotnet/wpf · error · ArgumentException

SR.Format(SR.UnexpectedParameterType, o.GetType()…

Error message

SR.Format(SR.UnexpectedParameterType, o.GetType(), typeof(FlowNode))

What it means

FlowNode.CompareTo throws ArgumentException when the object passed for comparison is not a FlowNode. WPF's flow document layout uses FlowNode comparison internally to order content nodes; passing any other type violates the IComparable contract this method implements.

Solutions

  1. Ensure every element compared against a FlowNode is actually a FlowNode instance
  2. Use 'is FlowNode' pattern matching to filter before comparing
  3. Sort within strongly typed List<FlowNode> collections rather than heterogeneous lists

Example fix

// before
int r = flowNode.CompareTo(otherObject);
// after
int r = otherObject is FlowNode fn ? flowNode.CompareTo(fn) : throw new InvalidOperationException("not a FlowNode");
Defensive patterns

Strategy: type-guard

Validate before calling

if (obj is FlowNode fn) { result = node.CompareTo(fn); }

Type guard

static bool IsFlowNode(object o) => o is FlowNode;

Try / catch

try { node.CompareTo(o); } catch (ArgumentException ex) when (ex.ParamName == "o") { /* handle wrong type */ }

Prevention

When it happens

Trigger: Calling FlowNode.CompareTo(obj) directly (or via a sort/compare delegate) with an object of a type other than FlowNode; null is separately rejected with ArgumentNullException.

Common situations: Custom sorting or binary-search code over mixed-type collections that include FlowNodes; reflection-based tooling or third-party code that calls IComparable without checking the concrete type first.

Understand the failure class

Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.

Related errors


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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/Documents/FlowNode.cs:113

            Debug.Assert(_fp != fn._fp || (_fp == fn._fp) && (_scopeId == fn._scopeId));

            return (this._fp == fn._fp);
        }


        /// <summary>
        /// Compare the flow order of this FlowNode to another FlowNode
        /// </summary>
        /// <param name="o">FlowNode to compare to</param>
        /// <returns>-1, 0, 1</returns>
        public int CompareTo(object o)
        {
            ArgumentNullException.ThrowIfNull(o);

            FlowNode fp = o as FlowNode;
            if (fp == null)
            {
                throw new ArgumentException(SR.Format(SR.UnexpectedParameterType, o.GetType(), typeof(FlowNode)), nameof(o));
            }

            if (Object.ReferenceEquals(this, fp))
            {
                return 0;
            }

            int fd = this._fp - fp._fp;
            if (fd == 0)
            {
                return 0;
            }
            else if (fd < 0)
            {
                return -1;
            }
            else
            {

View on GitHub (pinned to 81131a70a4)