dotnet/wpf · error · System.ArgumentException
SR.Collection_BadType
Error message
SR.Collection_BadType
What it means
This ArgumentException is thrown by the strongly-typed Cast(object) method that CollectionHelper generates for each typed collection in the WPF mcg codegen tool. IList.Add/IList.Insert receive System.Object, and the generator wraps them with a runtime type check so that only instances of the collection's element type are accepted. If the value is not assignable to [[type]], the collection rejects it rather than storing a wrongly-typed item.
Solutions
- Check the value's type before adding: only insert instances of the collection's declared element type.
- Convert or map the value to the expected element type prior to the Add/Insert call.
- If the collection type is wrong for your data, use a collection whose element type matches.
Example fix
// before
((IList)collection).Add(someObject); // throws if someObject is not [[type]]
// after
if (someObject is [[type]] typed)
{
((IList)collection).Add(typed);
} Defensive patterns
Strategy: type-guard
Validate before calling
if (value == null) throw new ArgumentNullException(nameof(value));
if (!(value is [[type]]))
throw new ArgumentException($"Expected [[type]], got {value.GetType().Name}"); Type guard
static bool Is acceptableItemType(object value) => value is [[type]]; // pattern-match before adding: if (value is [[type]] typed) ((IList)collection).Add(typed);
Try / catch
try { ((IList)collection).Add(value); }
catch (ArgumentException ex) when (ex.Message.Contains("wrong type") || ex.Message.Contains("BadType")) { /* convert or log the type mismatch */ } Prevention
- Use the generic collection API (IList<T>/Add(T)) instead of the non-generic IList overload.
- Validate element types at deserialization boundaries.
- Keep element-type declarations in sync with the data you insert.
When it happens
Trigger: Calling Add/Insert/Contains/Indexer-set on a generated typed collection through its non-generic IList interface with an object that is not of (or derived from) the declared element type, e.g. `((IList)stringCollection).Add(42)`.
Common situations: Reflection-based or XAML/BAML deserialization code inserting values of the wrong type; passing a base-type collection an incompatible item; API version changes that changed a collection's element type while caller code still adds old values.
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
- SR.Collection_BadDestArray
- SR.Collection_BadType
- SR.Format(SR.Collection_BadType, this.GetType().Name…
- SR.CannotConvertType
- SR.Collection_BadDestArray
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/7a53426daecbccac.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WpfGfx/codegen/mcg/helpers/CollectionHelper.cs:1168
/// </summary>
internal [[type]] Internal_GetItem(int i)
{
return _collection[i];
}
[[onInheritanceContextChangedCoreMethod]]
#endregion
#region Private Helpers
private [[type]] Cast(object value)
{
ArgumentNullException.ThrowIfNull(value);
if (!(value is [[type]]))
{
throw new System.ArgumentException(SR.Format(SR.Collection_BadType, this.GetType().Name, value.GetType().Name, "[[type]]"));
}
return ([[type]]) value;
}
// IList.Add returns int and IList<T>.Add does not. This
// is called by both Adds and IList<T>'s just ignores the
// integer
private int AddHelper([[type]] value)
{
int index = AddWithoutFiringPublicEvents(value);
// AddAtWithoutFiringPublicEvents incremented the version
WritePostscript();
return index;
}View on GitHub (pinned to 81131a70a4)