stride3d/stride · error · InvalidOperationException
Could not find serializer for type
Error message
Could not find serializer for type {typeof(T)}. What it means
This generic extension method on SerializationStream fetches the DataSerializer for T from the context's SerializerSelector and throws InvalidOperationException when none is registered. Unlike the internal code paths this is a public convenience API, so callers hitting it serialized a type that simply has no serializer available in the current serialization context.
Solutions
- Ensure the type is [DataContract] (or has a [DataSerializer]) and rebuild so generated serializers are registered
- Check stream.Context.SerializerSelector and use the default selector that includes the serializer for T
- Register T's assembly via Serialization.RegisterSerializationAssembly before serializing
- Write and register a custom DataSerializer for types you cannot annotate
- Catch InvalidOperationException and log typeof(T) to identify which type lacks a serializer
Example fix
// before
stream.Serialize(ref customThing); // InvalidOperationException: no serializer
// after
public class CustomThingSerializer : DataSerializer<CustomThing>
{ /* implement Serialize/Deserialize */ }
// register it, or mark CustomThing [DataContract] and rebuild Defensive patterns
Strategy: try-catch
Validate before calling
var selector = stream.Context.SerializerSelector;
if (selector.GetSerializer<T>() == null)
throw new InvalidOperationException($"Before calling Serialize, register a serializer for {typeof(T)}"); Type guard
static bool HasSerializerFor<T>(SerializationStream stream) =>
stream.Context.SerializerSelector.GetSerializer<T>() is not null; Try / catch
try
{
stream.Serialize(ref value);
}
catch (InvalidOperationException ex) when (ex.Message.Contains("Could not find serializer for type"))
{
logger.Error(ex, "No serializer registered for {Type}; add [DataContract]/[DataSerializer] or fix the SerializerSelector", typeof(T));
throw;
} Prevention
- Call this extension only for types covered by [DataContract]/generated serializers
- Verify the SerializationContext uses a SerializerSelector that includes your types
- Register serializer assemblies at startup before any save/load
- Add a smoke test that serializes every serializable model type
When it happens
Trigger: Calling stream.Serialize(ref myObj) (or Write) for a type T without a [DataContract]/generated or custom serializer; a custom SerializerSelector attached to the SerializationContext that excludes T's serializer; serializing before assembly registration of T's module; serializing unannotated third-party types.
Common situations: Quick custom binary save code writing component fields directly with stream.Serialize; serializing enums/structs from an assembly without generated serializers; swapping in a restricted SerializerSelector for partial serialization and forgetting the needed type; unit tests constructing a SerializationStream without the default selector.
Related errors
- No serializer available for type
- No serializer available for type id
- Unable to find a serializer for
- Unable to find a serializer for
- Could not find serializer for generic dependent type
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/f6f56d5e38e16491.
Report an issue: GitHub.
Appendix: source
Thrown at sources/core/Stride.Core/Serialization/SerializerExtensions.cs:93
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Write<T>(this SerializationStream stream, T obj)
{
Serialize(stream, ref obj, ArchiveMode.Serialize);
}
/// <summary>
/// Serializes the specified object.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="stream">The stream to serialize to.</param>
/// <param name="obj">The object to serialize.</param>
/// <param name="mode">The serialization mode.</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void Serialize<T>(this SerializationStream stream, ref T obj, ArchiveMode mode)
{
var dataSerializer = stream.Context.SerializerSelector.GetSerializer<T>();
if (dataSerializer == null)
throw new InvalidOperationException($"Could not find serializer for type {typeof(T)}.");
dataSerializer.PreSerialize(ref obj, mode, stream);
dataSerializer.Serialize(ref obj, mode, stream);
}
/// <summary>Serializes or deserializes the value using <see cref="SerializationStream.Serialize(Span{byte})"/>.</summary>
public static void Serialize<T>(this SerializationStream serializer, ref T value)
{
ref var b = ref Unsafe.As<T, byte>(ref value);
var span = MemoryMarshal.CreateSpan(ref b, Unsafe.SizeOf<T>());
serializer.Serialize(span);
}
/// <summary>
/// Reads a boolean value from the stream.
/// </summary>
/// <param name="stream">The stream.</param>
/// <returns>A boolean value read from the stream.</returns>View on GitHub (pinned to 96fad776d2)