dotnet/wpf · error · InvalidOperationException

SR.Format(SR.PropertyPathIndexWrongType…

Error message

SR.Format(SR.PropertyPathIndexWrongType, paramList[i].parenString, paramList[i].valueString)

What it means

ResolveIndexerParams throws this InvalidOperationException when an indexer parameter written as '(TypeName)valueString' cannot have valueString converted to TypeName. The type name resolved successfully, but the value string is not convertible to that type (e.g. a non-numeric string for Int32), so the indexer argument has the wrong type.

Solutions

  1. Correct the value string so it is convertible to the named type (e.g. '(Int32)42')
  2. Remove the '(TypeName)' prefix if the value should remain an uninterpreted string
  3. Pre-validate conversion with Convert.ChangeType or TypeConverter.CanConvertFrom before constructing the path
  4. Use the correct target type name matching the indexer's parameter type

Example fix

// before
var path = new PropertyPath("[(Int32)twelve]");
// after
var path = new PropertyPath("[(Int32)12]");
Defensive patterns

Strategy: validation

Validate before calling

bool convertible = int.TryParse(valueString, out _); // for (Int32) parameters
// general: System.ComponentModel.TypeConverter tc = System.ComponentModel.TypeDescriptor.GetConverter(typeof(int));
// tc.CanConvertFrom(typeof(string)) && tc.IsValid(valueString)

Type guard

bool CanParse<T>(string s) where T : IConvertible =>
    System.ComponentModel.TypeDescriptor.GetConverter(typeof(T)).IsValid(s);

Try / catch

try { path.ResolveIndexerParams(list, item, context, throwOnError: true); }
catch (InvalidOperationException ex) when (ex.Message.Contains("wrong type") || ex.Message.Contains("convert")) { /* fix the value string */ }

Prevention

When it happens

Trigger: Path like '(Int32)abc' where 'abc' is not parseable as an integer; type-qualified indexer parameters such as '[(Int32)xyz]' where the value string was meant for a string-typed indexer; culture/format mismatches in numeric strings.

Common situations: XAML binding indexer paths with typed parameters, e.g. Binding Path='[(sys:Int32)not-a-number]'; localizations altering numeric formatting (comma vs dot decimals); typos in the value string after copying a working path.

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/a4b9ad6ed55de810. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationFramework/System/Windows/PropertyPath.cs:754

                        // treated it like this, so to preserve compatibility...]
                        args[i].value = $"({paramList[i].parenString})";
                    }
                }
                else
                {
                    // both strings appear "(Double)3.14159" - value is type-converted from value string
                    args[i].type = GetTypeFromName(paramList[i].parenString, context);
                    if (args[i].type != null)
                    {
                        object value = GetTypedParamValue(paramList[i].valueString.Trim(), args[i].type, throwOnError);
                        if (value != null)
                        {
                            args[i].value = value;
                        }
                        else
                        {
                            if (throwOnError)
                                throw new InvalidOperationException(SR.Format(SR.PropertyPathIndexWrongType, paramList[i].parenString, paramList[i].valueString));
                            args[i].type = null;
                        }
                    }
                    else
                    {
                        // parens didn't hold a type name "(abc)xyz" - value is (uninterpreted) string
                        // [this could be considered an error, but the original code
                        // treated it like this, so to preserve compatibility...]
                        args[i].value = $"({paramList[i].parenString}){paramList[i].valueString}";
                    }
                }
            }
            return args;
        }

        private object GetTypedParamValue(string param, Type type, bool throwOnError)
        {
            object value = null;

View on GitHub (pinned to 81131a70a4)