LykosAI/StabilityMatrix · error · ArgumentException

Service of type is already registered for

Error message

Service of type {type} is already registered for {typeof(T)}

What it means

ServiceManager<T>.Register(Type, Func<T>) throws ArgumentException when the given type already has an instance or provider registered under the base type T. It keeps the instances/providers dictionaries one-to-one with service types.

Solutions

  1. Deduplicate the registration list before looping Register(Type, ...)
  2. Track already-registered types in the caller and skip them
  3. Use TryAdd-style semantics if replacement is desired (wrap in try/catch and continue on this specific ArgumentException)

Example fix

// before
foreach (var t in types) manager.Register(t, () => Create(t)); // second run throws
// after
foreach (var t in types)
    if (!manager.IsRegistered(t)) manager.Register(t, () => Create(t));
Defensive patterns

Strategy: validation

Validate before calling

foreach (var t in types)
    if (!manager.IsRegistered(t))
        manager.Register(t, CreateFactory(t));

Try / catch

try { manager.Register(type, providerFunc); }
catch (ArgumentException ex) when (ex.Message.Contains("already registered"))
{
    logger.LogDebug("{Type} already registered; ignoring", type);
}

Prevention

When it happens

Trigger: Calling manager.Register(typeof(IFoo), () => new Foo()) when typeof(IFoo) already exists in instances or providers from any prior Register call.

Common situations: Reflection-driven registration loops that run more than once; registering both via typeof(Interface) and typeof(Implementation) keys where one collides; duplicated setup in plugin loading.

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 LykosAI/StabilityMatrix@af93d6ef57 (2026-09-12). Data as JSON: /api/errors/67b3dc25c767085e. Report an issue: GitHub.

Appendix: source

Thrown at StabilityMatrix.Avalonia/Services/ServiceManager.cs:74

                    $"Service of type {typeof(TService)} is already registered for {typeof(T)}"
                );
            }

            // Return type is wrong during build with method group syntax
            // ReSharper disable once RedundantCast
            providers[typeof(TService)] = () => (TService)provider();
        }

        return this;
    }

    public void Register(Type type, Func<T> providerFunc)
    {
        lock (providers)
        {
            if (instances.ContainsKey(type) || providers.ContainsKey(type))
            {
                throw new ArgumentException($"Service of type {type} is already registered for {typeof(T)}");
            }

            providers[type] = providerFunc;
        }
    }

    /// <summary>
    /// Register a new service provider action with Scoped lifetime.
    /// The factory is called once per scope.
    /// </summary>
    public IServiceManager<T> RegisterScoped<TService>(Func<IServiceProvider, TService> provider)
        where TService : T
    {
        var type = typeof(TService);

        lock (providers)
        {
            if (instances.ContainsKey(type) || providers.ContainsKey(type))

View on GitHub (pinned to af93d6ef57)