{"record":{"id":"63dc1373844307a0","repo":"stride3d/stride","slug":"the-type-of-dictionary-does-not-have-a-parameterless","errorCode":null,"errorMessage":"The type of dictionary does not have a parameterless constructor.","messagePattern":"The type of dictionary does not have a parameterless constructor\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/assets/Stride.Core.Assets/Yaml/DictionaryWithIdsSerializer.cs","lineNumber":87,"sourceCode":"            if (!identifier.TryGet(item.Key, out var id))\n            {\n                id = ItemId.New();\n                identifier.Add(item.Key, id);\n            }\n            var keyWithId = Activator.CreateInstance(keyWithIdType, id, item.Key)!;\n            instance.Add(keyWithId, item.Value);\n        }\n\n        return instance;\n    }\n\n    /// <inheritdoc/>\n    protected override IDictionary CreatEmptyContainer(ITypeDescriptor descriptor)\n    {\n        var dictionaryDescriptor = (DictionaryDescriptor)descriptor;\n        var type = typeof(DictionaryWithItemIds<,>).MakeGenericType(dictionaryDescriptor.KeyType, dictionaryDescriptor.ValueType);\n        if (type.GetConstructor(Type.EmptyTypes) == null)\n            throw new InvalidOperationException(\"The type of dictionary does not have a parameterless constructor.\");\n        return (IDictionary)Activator.CreateInstance(type)!;\n    }\n\n    /// <inheritdoc/>\n    protected override void TransformAfterDeserialization(IDictionary container, ITypeDescriptor targetDescriptor, object targetCollection, ICollection<ItemId>? deletedItems = null)\n    {\n        var dictionaryDescriptor = (DictionaryDescriptor)targetDescriptor;\n        var type = typeof(DictionaryWithItemIds<,>).MakeGenericType(dictionaryDescriptor.KeyType, dictionaryDescriptor.ValueType);\n        if (!type.IsInstanceOfType(container))\n            throw new InvalidOperationException(\"The given container does not match the expected type.\");\n        var identifier = CollectionItemIdHelper.GetCollectionItemIds(targetCollection);\n        identifier.Clear();\n\n        // The collection may contain some initial data from its containing instance's ctor,\n        // let's replace the existing data with the data we have serialized\n        dictionaryDescriptor.Clear(targetCollection);\n\n        var enumerator = container.GetEnumerator();","sourceCodeStart":69,"sourceCodeEnd":105,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/assets/Stride.Core.Assets/Yaml/DictionaryWithIdsSerializer.cs#L69-L105","documentation":"DictionaryWithIdsSerializer.CreatEmptyContainer constructs DictionaryWithItemIds<TKey,TValue> from the target dictionary's key/value types and requires a public parameterless constructor to instantiate it as the deserialization container. When the constructed generic type has no parameterless ctor, it throws InvalidOperationException, mirroring the collection-side guard.","triggerScenarios":"Deserializing an asset whose dictionary member leads to DictionaryWithItemIds<TKey,TValue> lacking a default ctor; source modifications removing the default constructor; trimming/AOT stripping the constructor; wrong KeyType/ValueType resolution building an unexpected generic instantiation.","commonSituations":"Custom asset dictionary members with exotic key/value types; patched Stride source; IL trimming in published editor builds breaking reflection-based activation.","solutions":["Restore a public parameterless constructor on DictionaryWithItemIds<TKey,TValue>","Fix the generic construction so key/value types match the intended concrete types","Add linker/trimmer preservation for the parameterless constructor","Ensure the asset member's declared dictionary type matches what the serializer expects"],"exampleFix":"// before (DictionaryWithItemIds.cs)\npublic DictionaryWithItemIds(IDictionary<TKey,TValue> source) { ... } // no parameterless ctor\n// after\npublic DictionaryWithItemIds() { }\npublic DictionaryWithItemIds(IDictionary<TKey,TValue> source) { ... }","handlingStrategy":"validation","validationCode":"var kvTypes = GetDictionaryKVTypes(myDictionaryType);\nvar containerType = typeof(DictionaryWithItemIds<,>).MakeGenericType(kvTypes.KeyType, kvTypes.ValueType);\nif (containerType.GetConstructor(Type.EmptyTypes) == null)\n    throw new InvalidOperationException($\"{containerType} lost its parameterless ctor; fix before asset serialization\");","typeGuard":null,"tryCatchPattern":"try { SerializeAssets(stream, asset); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"parameterless constructor\"))\n{\n    Log.Error(\"Dictionary serializer container broken: {Message}\", ex.Message);\n    throw;\n}","preventionTips":["Keep a public parameterless constructor on DictionaryWithItemIds<TKey,TValue>","Add a reflection test asserting the container types have parameterless ctors","Configure trimmer preserve rules for serializer container types in published builds","Verify dictionary member key/value types resolve to the concrete types the serializer expects"],"tags":["csharp","invalidoperationexception","yaml","serialization","reflection"],"backgroundTag":"invalid-constructor-argument","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}