dotnet/wpf · error · ArgumentException

SR.Collection_BadType

Error message

SR.Collection_BadType

What it means

The private Cast(object value) helper throws ArgumentException (SR.Collection_BadType) when a value added to the collection is not a Transform3D instance. It is used by the non-generic IList paths (Add/Insert, reached via MaterialCollection-style non-generic callers) after a null check.

Solutions

  1. Ensure the object is a Transform3D (e.g. RotateTransform3D, TranslateTransform3D, TransformGroup) before adding.
  2. If the object is a Transform (2D), wrap/convert appropriately or use the correct 3D transform class.
  3. Use the generic Transform3DCollection.Add(Transform3D) so the compiler catches type errors.

Example fix

// before
((IList)collection).Add(new RotateTransform()); // 2D transform
// after
((IList)collection).Add(new RotateTransform3D(new AxisAngleRotation3D(axis, 45)));
Defensive patterns

Strategy: type-guard

Validate before calling

if (value is Transform3D t) ((IList)collection).Add(t);

Type guard

bool IsTransform3D(object v) => v is Transform3D;

Try / catch

try { ((IList)collection).Add(obj); } catch (ArgumentException) { /* wrong element type; log or convert */ }

Prevention

When it happens

Trigger: Calling the non-generic IList.Add(object) or IList.Insert(int, object) with an object that is not a Transform3D, e.g. adding a Visual3D, a Model3D, or a loosely-typed deserialized object.

Common situations: Mixing up 3D object types in code that builds scenes dynamically; passing items from a differently-typed collection; data binding or deserialization that supplies the wrong type.

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

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media3D/Generated/Transform3DCollection.cs:516

                DependencyObject inheritanceChild = _collection[i];
                if (inheritanceChild != null && inheritanceChild.InheritanceContext == this)
                {
                    inheritanceChild.OnInheritanceContextChanged(args);
                }
            }
        }

        #endregion

        #region Private Helpers

        private Transform3D Cast(object value)
        {
            ArgumentNullException.ThrowIfNull(value);

            if (!(value is Transform3D))
            {
                throw new System.ArgumentException(SR.Format(SR.Collection_BadType, this.GetType().Name, value.GetType().Name, "Transform3D"));
            }

            return (Transform3D) 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(Transform3D value)
        {
            int index = AddWithoutFiringPublicEvents(value);

            // AddAtWithoutFiringPublicEvents incremented the version

            WritePostscript();

            return index;
        }

View on GitHub (pinned to 81131a70a4)