LykosAI/StabilityMatrix · error · ArgumentException

Service of type is already registered as Scoped.

Error message

Service of type {type} is already registered as Scoped.

What it means

RegisterScoped<TService> throws this second ArgumentException when instances/providers are clear but scopedProviders.TryAdd fails — meaning TService is already registered as scoped with another factory. It distinguishes lifetime conflicts from duplicate scoped registrations.

Solutions

  1. Register each scoped service exactly once
  2. If a module may run twice, guard registration with a bool or ContainsKey check
  3. Choose a single owner for the registration of shared services

Example fix

// before
manager.RegisterScoped<ISession>(sp => new Session());
manager.RegisterScoped<ISession>(sp => new Session(sp.GetUser())); // throws
// after
if (!manager.IsRegistered<ISession>())
    manager.RegisterScoped<ISession>(sp => new Session(sp.GetUser()));
Defensive patterns

Strategy: validation

Validate before calling

if (!manager.IsRegistered<ISession>())
    manager.RegisterScoped<ISession>(sp => new Session(sp));

Try / catch

try { manager.RegisterScoped<ISession>(provider); }
catch (ArgumentException ex) when (ex.Message.Contains("already registered as Scoped"))
{
    logger.LogDebug("ISession already scoped-registered; skipping");
}

Prevention

When it happens

Trigger: Calling RegisterScoped<TService>(provider) twice, or RegisterScoped<TService> after RegisterScoped(typeof(TService), otherProvider) already stored a factory.

Common situations: DI setup method invoked twice (e.g. on re-login or test fixture re-initialization); two modules each registering their own factory for the same scoped interface.

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/e7f5a398f1995dfa. Report an issue: GitHub.

Appendix: source

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

    /// <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))
                throw new ArgumentException(
                    $"Service of type {type} is already registered with a different lifetime."
                );

            if (!scopedProviders.TryAdd(type, sp => provider(sp))) // Store as base type T
                throw new ArgumentException($"Service of type {type} is already registered as Scoped.");
        }

        return this;
    }

    /// <summary>
    /// Register a new service provider action with Scoped lifetime.
    /// The factory is called once per scope.
    /// </summary>
    public IServiceManager<T> RegisterScoped(Type type, Func<IServiceProvider, T> provider)
    {
        lock (providers)
        {
            if (instances.ContainsKey(type) || providers.ContainsKey(type))
                throw new ArgumentException(
                    $"Service of type {type} is already registered with a different lifetime."
                );

View on GitHub (pinned to af93d6ef57)