stride3d/stride · error · ArgumentException
Service is already registered with this type
Error message
Service is already registered with this type
What it means
ServiceRegistry.AddService registers a service instance per service type in a dictionary; only one instance per type is allowed. Adding a second service for the same typeof(T) fails the TryAdd and throws this ArgumentException.
Solutions
- Call RemoveService<T>() (or dispose the registry) before re-adding the service
- Use GetOrCreate<T>() to fetch the existing instance instead of AddService
- Fix double initialization so AddService runs only once per type
Example fix
// before
services.AddService<ICameraProcessor>(cameraProcessor);
services.AddService<ICameraProcessor>(cameraProcessor); // throws
// after
if (services.GetInstance<ICameraProcessor>() == null)
services.AddService<ICameraProcessor>(cameraProcessor); Defensive patterns
Strategy: validation
Validate before calling
if (registry.GetInstance<T>() != null)
return registry.GetInstance<T>(); // already registered, reuse it
registry.AddService<T>(service); Try / catch
try { registry.AddService(service); }
catch (ArgumentException e) when (e.Message.Contains("already registered"))
{ service = registry.GetInstance<T>(); } // fall back to existing instance Prevention
- Prefer GetOrCreate<T>() over AddService for idempotent startup
- Call RemoveService<T>() in test teardown when sharing a registry
- Initialize services in exactly one place
When it happens
Trigger: Calling AddService<T>(T) when an instance of T (the exact service type) is already registered, e.g. double-initialization of Game, running processor setup twice, or two tests sharing a registry without cleanup.
Common situations: Unit tests reusing a shared ServiceRegistry across test cases without RemoveService; app startup code that registers a service both in a bootstrapper and in game initialization.
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- The upgrader overlaps with another upgrader.
- Stride.Games.AutoTesting
- Input Source already added
- Duplicate collider added
- NavigationProcessor can not access the game systems…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/13843234b35e46f7.
Report an issue: GitHub.
Appendix: source
Thrown at sources/core/Stride.Core/ServiceRegistry.cs:74
}
return null;
}
/// <inheritdoc />
/// <remarks>
/// This implementation triggers the <see cref="ServiceAdded"/> event after a service is successfully added.
/// </remarks>
public void AddService<T>(T service)
where T : class
{
ArgumentNullException.ThrowIfNull(service);
var type = typeof(T);
lock (registeredService)
{
if (!registeredService.TryAdd(type, service))
throw new ArgumentException("Service is already registered with this type", nameof(type));
}
OnServiceAdded(new ServiceEventArgs(type, service));
}
/// <inheritdoc />
/// <remarks>
/// This implementation triggers the <see cref="ServiceRemoved"/> event after a service is successfully removed.
/// If the service type is not found, this method does nothing.
/// </remarks>
public void RemoveService<T>()
where T : class
{
var type = typeof(T);
object? oldService;
lock (registeredService)
{
registeredService.Remove(type, out oldService);
}View on GitHub (pinned to 96fad776d2)