{"record":{"id":"fe9f98754557a4ca","repo":"stride3d/stride","slug":"the-given-container-does-not-match-the-expected-type","errorCode":null,"errorMessage":"The given container does not match the expected type.","messagePattern":"The given container does not match the expected type\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/assets/Stride.Core.Assets/Yaml/CollectionWithIdsSerializer.cs","lineNumber":114,"sourceCode":"    }\n\n    /// <inheritdoc/>\n    protected override IDictionary CreatEmptyContainer(ITypeDescriptor descriptor)\n    {\n        var collectionDescriptor = (CollectionDescriptor)descriptor;\n        var type = typeof(CollectionWithItemIds<>).MakeGenericType(collectionDescriptor.ElementType);\n        if (type.GetConstructor(Type.EmptyTypes) == null)\n            throw new InvalidOperationException(\"The type of collection 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 collectionDescriptor = (CollectionDescriptor)targetDescriptor;\n        var type = typeof(CollectionWithItemIds<>).MakeGenericType(collectionDescriptor.ElementType);\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        collectionDescriptor.Clear(targetCollection);\n\n        var i = 0;\n        var enumerator = container.GetEnumerator();\n        while (enumerator.MoveNext())\n        {\n            collectionDescriptor.Add(targetCollection, enumerator.Value);\n            if (targetDescriptor.Category == DescriptorCategory.Set)\n            {\n                identifier.Add(enumerator.Value!, (ItemId)enumerator.Key);\n            }\n            else\n            {","sourceCodeStart":96,"sourceCodeEnd":132,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/assets/Stride.Core.Assets/Yaml/CollectionWithIdsSerializer.cs#L96-L132","documentation":"After deserialization, CollectionWithIdsSerializer.TransformAfterDeserialization checks that the intermediate container is an instance of the expected closed generic CollectionWithItemIds<T> before copying item ids into the real collection. A mismatched container means the pipeline produced the wrong intermediate object, so it throws InvalidOperationException to prevent silently losing per-item ids.","triggerScenarios":"A custom/derived serializer returning a different IDictionary container; chain changes so CreatEmptyContainer and TransformAfterDeserialization disagree; serializing an object whose descriptor element type changed between container creation and transform.","commonSituations":"Patched serializers or custom chained serializers for assets; version-skew between plugin code building containers and the Stride asset serializer; regression tests feeding hand-built dictionaries into the transform step.","solutions":["Ensure the container passed through the chain is created by CreatEmptyContainer (CollectionWithItemIds<T>) and not replaced","Remove or fix custom chained serializers that swap the intermediate container","Verify target descriptor's element type matches the one used to build the container","Revert to stock Stride serializer classes for asset collections"],"exampleFix":"// before\nIDictionary container = new Dictionary<object, object>(); // wrong type\nserializer.TransformObjectAfterRead(container, descriptor, target);\n// after\nvar container = serializerInstance.CreateContainerForTest(descriptor); // produces CollectionWithItemIds<T>\nserializer.TransformObjectAfterRead(container, descriptor, target);","handlingStrategy":"type-guard","validationCode":"var expectedType = typeof(CollectionWithItemIds<>).MakeGenericType(elementType);\nif (!expectedType.IsInstanceOfType(container))\n    throw new InvalidOperationException($\"Container must be {expectedType}, got {container?.GetType()}\");","typeGuard":"static bool IsCollectionWithItemIdsOf(IDictionary? c, Type elementType) =>\n    c != null && typeof(CollectionWithItemIds<>).MakeGenericType(elementType).IsInstanceOfType(c);","tryCatchPattern":"try { serializer.RunTransform(container, descriptor, target); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"does not match the expected type\"))\n{\n    Log.Error(\"Intermediate collection container replaced in chain: {Message}\", ex.Message);\n    throw;\n}","preventionTips":["Always obtain intermediate containers from the serializer's own CreatEmptyContainer","Don't insert custom chained serializers that swap IDictionary intermediates","Verify element types haven't changed between container creation and transformation","Pin Stride serializer classes; avoid subclassing them in plugins"],"tags":["csharp","invalidoperationexception","yaml","serialization","type-mismatch"],"backgroundTag":"type-mismatch","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"}