stride3d/stride · error · ArgumentException
Expecting a type inheriting from…
Error message
Expecting a type inheriting from System.Collections.Generic.IDictionary<T,K>
What it means
DictionaryDescriptor requires the supplied type to implement the generic IDictionary<TKey,TValue> interface (checked by its IsDictionary helper). If the type is not a generic dictionary — e.g. a Hashtable, non-generic IDictionary, or a plain class — the constructor throws ArgumentException.
Solutions
- Use System.Collections.Generic.Dictionary<TKey,TValue> or any type implementing IDictionary<TKey,TValue>.
- Migrate non-generic IDictionary/Hashtable fields to generic dictionaries.
- If you own the collection type, add IDictionary<TKey,TValue> to its interfaces.
- Route truly non-dictionary types to the appropriate descriptor (ListDescriptor, ObjectDescriptor) via the factory.
Example fix
// before public Hashtable Settings; // after public Dictionary<string, object> Settings;
Defensive patterns
Strategy: type-guard
Validate before calling
if (!DictionaryDescriptor.IsDictionary(type))
throw new ArgumentException("Type must implement IDictionary<TKey,TValue>", nameof(type)); Type guard
static bool IsGenericDictionary(Type t) => t.GetInterfaces().Any(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IDictionary<,>));
Try / catch
try { var d = new DictionaryDescriptor(factory, type, true, naming); }
catch (ArgumentException ex) when (ex.Message.Contains("IDictionary")) { /* use a generic dictionary type */ } Prevention
- Use Dictionary<TKey,TValue> (or implement IDictionary<TKey,TValue>) in serialized models.
- Replace Hashtable/non-generic IDictionary fields during migration to Stride serialization.
When it happens
Trigger: new DictionaryDescriptor(factory, typeof(Hashtable), ...) or typeof(IDictionary) (non-generic) or any non-dictionary type; passing a custom collection that only implements IDictionary (non-generic).
Common situations: See trigger scenarios.
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
- Expecting a type inheriting from…
- Type vertex can't be a byte
- A NodeIndex instance cannot be passed as the value of…
- Argument must be of type Angle.
- Behavior of type ' ' must be bound to objects of type ' '…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/b14ebde569fbd91b.
Report an issue: GitHub.
Appendix: source
Thrown at sources/core/Stride.Core.Reflection/TypeDescriptors/DictionaryDescriptor.cs:34
Action<object, object, object?> addMethod;
Action<object, object> removeMethod;
Action<object, object, object?> setValueMethod;
Func<object, object, bool> containsKeyMethod;
Func<object, ICollection> getKeysMethod;
Func<object, ICollection> getValuesMethod;
Func<object, object, object?> getValueMethod;
Func<object, IEnumerable<KeyValuePair<object, object?>>> getEnumeratorMethod;
Action<object> clearMethod;
#pragma warning disable CS8618
// This warning is disabled because the necessary initialization will occur
// in the CreateDictionaryDelegates<T>() method, not in the constructor.
public DictionaryDescriptor(ITypeDescriptorFactory factory, Type type, bool emitDefaultValues, IMemberNamingConvention namingConvention)
: base(factory, type, emitDefaultValues, namingConvention)
{
if (!IsDictionary(type))
throw new ArgumentException(@"Expecting a type inheriting from System.Collections.Generic.IDictionary<T,K>", nameof(type));
// extract Key, Value types from IDictionary<??, ??>
var interfaceType = type.GetInterface(typeof(IDictionary<,>))!;
KeyType = interfaceType.GetGenericArguments()[0];
ValueType = interfaceType.GetGenericArguments()[1];
IsGenericDictionary = true;
// if the type has late bound generics, no delegates can be created as the type is invalid for calling collection operations
if (type.ContainsGenericParameters)
return;
var createMethod = typeof(DictionaryDescriptor).GetMethod(nameof(CreateDictionaryDelegates), BindingFlags.NonPublic | BindingFlags.Instance);
var genericCreateMethod = createMethod!.MakeGenericMethod([KeyType, ValueType]);
genericCreateMethod!.Invoke(this, []);
}
void CreateDictionaryDelegates<TKey, TValue>()
{
addMethod = (dictionary, key, value) => ((IDictionary<TKey, TValue?>)dictionary).Add((TKey)key, (TValue?)value);View on GitHub (pinned to 96fad776d2)