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

  1. Call RemoveService<T>() (or dispose the registry) before re-adding the service
  2. Use GetOrCreate<T>() to fetch the existing instance instead of AddService
  3. 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

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


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)