stride3d/stride · error · InvalidOperationException

Could not find serializer for generic dependent type

Error message

Could not find serializer for generic dependent type {0} when processing {1}

What it means

ScanSerializerDependencies verifies that every generic argument (dependent type) of a registered serializable type has its own serializer. When ResolveSerializer returns null for one of them, this error is thrown naming the dependent type and the owner type.

Solutions

  1. Add [DataContract] to the dependent type so a serializer is generated
  2. Create/register an explicit DataSerializer for the dependent type
  3. Ensure the assembly defining the dependent type is processed before/in the same run
  4. Mark the member with [DataMemberIgnore] if the dependent type need not be serialized

Example fix

// before
public class Mesh { public List<VertData> Vertices; } // VertData not serializable
// after
[DataContract]
public class VertData { public float X, Y, Z; }
Defensive patterns

Strategy: validation

Validate before calling

static void EnsureElementSerializable(Type collectionType)
{
    foreach (var arg in collectionType.GetGenericArguments())
        if (!arg.IsDefined(typeof(DataContractAttribute)) && !arg.IsPrimitive && !arg.IsEnum)
            throw new InvalidOperationException($"{arg.Name} needs [DataContract] or a DataSerializer");
}

Type guard

static bool HasSerializer(Type t) =>
    t.IsPrimitive || t.IsEnum || t == typeof(string) || t.IsDefined(typeof(DataContractAttribute));

Try / catch

try { ProcessCollection(listType); }
catch (InvalidOperationException ex) when (ex.Message.Contains("generic dependent type"))
{
    logger.Error($"Add a serializer for the element type: {ex.Message}");
}

Prevention

When it happens

Trigger: A generic serializable type like List<MyType> is registered, but MyType (the dependent type) has no resolvable serializer at that point — no DataContract, no DataSerializer, and not part of the current processing set.

Common situations: Using a custom class as a generic collection element without [DataContract]; a serializer assembly that references types from an assembly not being processed; typo in a namespace so the element type resolves to nothing.

Understand the failure class

Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/7bf58c4f42e3b201. Report an issue: GitHub.

Appendix: source

Thrown at sources/core/Stride.Core.AssemblyProcessor/Serializers/CecilSerializerContext.cs:517

        // Detect all ldtoken (attributes would have been better, but unfortunately C# doesn't allow generics in attributes)
        foreach (var inst in enumerateMethod.Body.Instructions)
        {
            if (inst.OpCode.Code != Code.Ldtoken)
                continue;

            var type = (TypeReference)inst.Operand;

            // Try to "close" generics type with serializer type as a context
            var dependentType = ResolveGenericsVisitor.Process(serializableTypeInfo.SerializerType, type);
            if (dependentType.ContainsGenericParameter())
                continue;

            // Import type so that it becomes local to the assembly
            // (otherwise SerializableTypeInfo.Local will be false and it won't be instantiated)
            var importedType = Assembly.MainModule.ImportReference(dependentType);
            if (ResolveSerializer(importedType) == null)
            {
                throw new InvalidOperationException(string.Format("Could not find serializer for generic dependent type {0} when processing {1}", dependentType, dataType));
            }
        }
    }

    private ProfileInfo GetSerializableTypes(string profile)
    {
        if (!SerializableTypesProfiles.TryGetValue(profile, out var profileInfo))
        {
            profileInfo = new ProfileInfo();
            SerializableTypesProfiles.Add(profile, profileInfo);
        }
        return profileInfo;
    }

    internal class SerializableTypeInfo
    {
        public TypeReference SerializerType { get; internal set; }
        public DataSerializerGenericMode Mode { get; internal set; }

View on GitHub (pinned to 96fad776d2)