stride3d/stride · error · InvalidOperationException
A serializer factory selector must be sealed before being…
Error message
A serializer factory selector must be sealed before being used.
What it means
GetSerializer throws InvalidOperationException if the selector was not sealed before use. Sealing finalizes the factory list; using an unsealed selector could yield inconsistent serializer selection and break caching, so the library refuses to operate until Seal() is called.
Solutions
- Call Seal() on the selector after adding all factories and before any serialization/deserialization.
- Ensure initialization completes even on error paths (try/finally or explicit init method).
- Use the standard Serializer construction path that seals the selector automatically.
- Check for swallowed exceptions earlier in setup that skipped the Seal call.
- Guard usage: assert selector is sealed in your wrapper before serializing.
Example fix
// before var selector = new SerializerFactorySelector(); selector.TryAddFactory(new MyFactory()); serializer = new Serializer(selector); // GetSerializer later throws: not sealed // after var selector = new SerializerFactorySelector(); selector.TryAddFactory(new MyFactory()); selector.Seal(); serializer = new Serializer(selector);
Defensive patterns
Strategy: validation
Validate before calling
// assert before use System.Diagnostics.Debug.Assert(selectorSealed, "Call Seal() on the SerializerFactorySelector before serializing");
Try / catch
try { var s = selector.GetSerializer(ctx, descriptor); }
catch (InvalidOperationException ex) when (ex.Message.Contains("must be sealed")) { throw new InvalidOperationException("Serializer was used before Seal() — finish initialization first", ex); } Prevention
- Always call Seal() immediately after adding factories
- Centralize serializer construction in one factory method that seals
- Check initialization order in DI composition roots
- Use the default Serializer constructor which handles sealing
When it happens
Trigger: Calling GetSerializer(context, typeDescriptor) on a SerializerFactorySelector whose Seal() was never invoked — typically a selector built manually or wired into a Serializer without finishing registration/sealing.
Common situations: Custom serializer setup code that adds factories but forgets Seal(); DI-created selectors where no one calls Seal; partially completed initialization after an earlier exception aborted setup.
Understand the failure class
Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.
Related errors
- Cannot add a factory to a serializer factory selector once…
- The queue is empty
- factory
- Unable to find a serializer for the type
- An IObjectNode was expected when processing the path
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/2ac343da0ac11728.
Report an issue: GitHub.
Appendix: source
Thrown at sources/core/Stride.Core.Yaml/Serialization/SerializerFactorySelector.cs:40
{
if (factory == null) throw new ArgumentNullException(nameof(factory));
if (isSealed) throw new InvalidOperationException("Cannot add a factory to a serializer factory selector once it is sealed.");
if (CanAddSerializerFactory(factory))
{
factories.Add(factory);
}
}
/// <inheritdoc/>
public void Seal()
{
isSealed = true;
}
/// <inheritdoc/>
public IYamlSerializable GetSerializer(SerializerContext context, ITypeDescriptor typeDescriptor)
{
if (!isSealed) throw new InvalidOperationException("A serializer factory selector must be sealed before being used.");
IYamlSerializable serializer;
// First try, with just a read lock
serializerLock.EnterReadLock();
var found = serializers.TryGetValue(typeDescriptor.Type, out serializer);
serializerLock.ExitReadLock();
if (!found)
{
// Not found, let's take exclusive lock and try again
serializerLock.EnterWriteLock();
if (!serializers.TryGetValue(typeDescriptor.Type, out serializer))
{
foreach (var factory in factories)
{
serializer = factory.TryCreate(context, typeDescriptor);
if (serializer != null)
{View on GitHub (pinned to 96fad776d2)