stride3d/stride · error · ArgumentException

No serializer available for type

Error message

No serializer available for type 

What it means

During member serialization of a struct/value type, the serializer selector returned null even after a lookup, meaning no DataSerializer is registered for the type's FullName. Stride's serialization is registry-based: types must have generated or custom serializers to cross the stream, so it throws ArgumentException rather than silently skipping the member.

Solutions

  1. Add a [DataSerializer] for the type or make it [DataContract] and regenerate serializers (build with Stride's codegen)
  2. Ensure the assembly containing the type is registered via Serialization.RegisterSerializationAssembly
  3. Check the SerializerSelector/profile actually includes serializers for that type instead of filtering them out
  4. If the type should not be serialized, mark the member [DataMemberIgnore] to exclude it
  5. Register a custom DataSerializer via SerializerSelector registration for third-party types you can't annotate

Example fix

// before
public struct MyId { public int Value; } // no serializer -> ArgumentException
// after
[DataContract]
public struct MyId { public int Value; }
// plus regenerate serializer assembly or:
[DataSerializer(typeof(MyIdSerializer))]
Defensive patterns

Strategy: type-guard

Validate before calling

// before serializing a struct member, confirm a serializer exists
var serializer = context.SerializerSelector.GetSerializer(memberType);
if (serializer == null) throw new InvalidOperationException($"No serializer registered for {memberType}");

Type guard

static bool HasSerializer(SerializerSelector selector, Type t) =>
    selector.GetSerializer(t) is not null;

Try / catch

try
{
    stream.Serialize(ref value);
}
catch (ArgumentException ex) when (ex.Message.StartsWith("No serializer available"))
{
    logger.Error(ex, "Add [DataContract]/[DataSerializer] or regenerate serializers for the type in question");
    throw;
}

Prevention

When it happens

Trigger: Serializing an object graph that contains a struct type with no [DataSerializer]/generated serializer and not in SerializerSelector's known set; a custom type added to a component/asset without running the Stride serializer codegen; a SerializerSelector that excludes the serializer needed for that member type.

Common situations: Adding a plain C# struct (e.g. custom vector/ID type) to an EntityComponent without a DataSerializer; forgetting to regenerate the serializer assembly after adding a new serializable type; using a custom SerializerSelector profile that filters out the serializer; referencing a type from an assembly not registered for serialization.

Related errors


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

Appendix: source

Thrown at sources/core/Stride.Core/Serialization/MemberSerializerCore.ttinclude:30

<# if (supportsReuseReferences || supportsNonSealed || supportsNullDataSerializer) { #>
        var context = stream.Context;
<# } #>

<# if (supportsValueType) { #>
<# if (supportsGenerics) { #>
        if (isValueType)
<# } else { #>
        if (objType.IsValueType)
<# } #>
        {
<# if (supportsNullDataSerializer) { #>
            if (dataSerializer is null)
            {
                dataSerializer = <#= serializerCastExpr #>context.SerializerSelector.GetSerializer(<#= typeExpr #>);

                // If we still have no serializer, throw an exception
                if (dataSerializer is null)
                    throw new ArgumentException("No serializer available for type " + <#= typeExpr #>.FullName);
            }
<# } // supportsNullDataSerializer #>

            // Structure, no need to check for inheritance or null values.
            dataSerializer.Serialize(ref obj, mode, stream);

            return;
        }

<# } #>

<# if (supportsNonSealed || supportsReuseReferences) { #>
        // Serialize either with dataSerializer if obj is really of type T, otherwise look for appropriate serializer.
        SerializeClassFlags flags;
<# } #>
<# if (supportsReuseReferences) { #>
        bool reuseReferences = context.SerializerSelector.ReuseReferences;
        int index;

View on GitHub (pinned to 96fad776d2)