stride3d/stride · error · InvalidOperationException
Cannot add a factory to a serializer factory selector once…
Error message
Cannot add a factory to a serializer factory selector once it is sealed.
What it means
TryAddFactory throws InvalidOperationException once the selector has been sealed (Seal() sets isSealed). Sealing is a one-way transition: after it, the set of serializer factories is frozen so GetSerializer can safely cache results; late additions are rejected to protect the caching invariant.
Solutions
- Register all factories before Seal()/first use; seal only after registration completes.
- Restructure lazy plugin loading to happen at initialization time.
- Give each subsystem its own SerializerFactorySelector instead of sharing a sealed one.
- Catch InvalidOperationException and treat it as a configuration-order bug (log it).
- Check an isSealed flag of your own before calling TryAddFactory.
Example fix
// before selector.Seal(); selector.TryAddFactory(myFactory); // throws // after selector.TryAddFactory(myFactory); selector.Seal();
Defensive patterns
Strategy: validation
Validate before calling
// track sealing yourself
if (sealedFlag) throw new InvalidOperationException("Serializer configuration is closed; register factories earlier"); Try / catch
try { selector.TryAddFactory(factory); }
catch (InvalidOperationException ex) { log.Error("Factory registration after seal — restructure initialization", ex); throw; } Prevention
- Complete all factory registration before calling Seal()
- Never lazily register factories during first deserialization
- Avoid sharing a sealed selector across independently configured subsystems
- Treat Seal() as the end of a dedicated init phase
When it happens
Trigger: Calling TryAddFactory after Seal() was invoked — e.g. registering factories lazily while deserialization already started, or two components both configuring a shared serializer with one sealing early.
Common situations: Plugin systems that add custom serializers on first use; race conditions where one thread begins deserializing (sealing implicitly) while another registers; static/shared serializer instances configured in multiple places.
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
- A serializer factory selector must be sealed before being…
- 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/21eda938b33bdc9f.
Report an issue: GitHub.
Appendix: source
Thrown at sources/core/Stride.Core.Yaml/Serialization/SerializerFactorySelector.cs:24
using Stride.Core.Reflection;
namespace Stride.Core.Yaml.Serialization
{
/// <summary>
/// Base class that implements <see cref="ISerializerFactorySelector"/>.
/// </summary>
public abstract class SerializerFactorySelector : ISerializerFactorySelector
{
private readonly Dictionary<Type, IYamlSerializable> serializers = new Dictionary<Type, IYamlSerializable>();
private readonly List<IYamlSerializableFactory> factories = new List<IYamlSerializableFactory>();
private readonly ReaderWriterLockSlim serializerLock = new ReaderWriterLockSlim();
private bool isSealed;
/// <inheritdoc/>
public void TryAddFactory(IYamlSerializableFactory factory)
{
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;
View on GitHub (pinned to 96fad776d2)