dotnet/wpf · error · ArgumentException
SR.ServiceTypeAlreadyAdded
Error message
SR.ServiceTypeAlreadyAdded
What it means
ServiceProviders.AddService throws ArgumentException(SR.ServiceTypeAlreadyAdded) when AddService is called for a serviceType that is already registered with a different service instance. The service map is write-once per type. This prevents silently replacing an already-published service object.
Solutions
- Check GetService(serviceType) for null before calling AddService and skip if already present.
- Register each service type exactly once during initialization.
- Use the same service instance if re-registration is intentional (the check passes when the stored instance equals the new one).
- Catch ArgumentException and treat it as 'already registered' if idempotent registration is desired.
Example fix
// before
providers.AddService(typeof(IMyService), new MyService());
providers.AddService(typeof(IMyService), new MyService()); // throws
// after
if (providers.GetService(typeof(IMyService)) == null)
providers.AddService(typeof(IMyService), new MyService()); Defensive patterns
Strategy: validation
Validate before calling
bool canAdd = providers.GetService(typeof(IMyService)) == null;
Type guard
null
Try / catch
try { providers.AddService(typeof(IMyService), svc); }
catch (ArgumentException) { /* already registered with a different instance */ } Prevention
- Register each service type exactly once in a single init path.
- Check GetService before AddService for idempotent registration.
- Avoid re-running service registration on repeated initialization.
When it happens
Trigger: Calling AddService(typeof(X), serviceA) and then AddService(typeof(X), serviceB) on the same ServiceProviders instance; re-registering a service during a second initialization pass; multiple components each attempting to register the same service type.
Common situations: Double initialization of a designer/serializer context (e.g. adding the same service to an EditorContext twice); shared service providers reused across parse/serialize operations; DI-style code assuming Add behaves like a dictionary indexer set.
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
- NotImplementedException
- SR.Format(SR.DeferringLoaderNoContext…
- SR.Format(SR.DeferringLoaderNoContext…
- SR.Format(SR.MarkupExtensionNoContext, GetType().Name…
- SR.Format(SR.MarkupExtensionNoContext, GetType().Name…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/5f931084e3a5c3e2.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/WindowsBase/System/Windows/Markup/ServiceProviders.cs:47
#endregion
/// <summary>
/// Add a new service
/// </summary>
/// <param name="serviceType"></param>
/// <param name="service"></param>
public void AddService(Type serviceType, Object service)
{
ArgumentNullException.ThrowIfNull(serviceType);
ArgumentNullException.ThrowIfNull(service);
if (!_objDict.ContainsKey(serviceType))
{
_objDict.Add(serviceType, service);
}
else if (_objDict[serviceType] != service)
{
throw new ArgumentException(SR.ServiceTypeAlreadyAdded, nameof(serviceType));
}
}
private Dictionary<Type,Object> _objDict = new Dictionary<Type,Object>();
}
}
View on GitHub (pinned to 81131a70a4)