stride3d/stride · error · InvalidOperationException
Multiple services match the given type.
Error message
Multiple services match the given type.
What it means
Thrown by ViewModelServiceProvider.TryGet when more than one registered service is an instance of the requested serviceType. TryGet is meant to resolve a single unambiguous service; the provider's services list is not keyed by type, so a request matching multiple registrations is ambiguous and cannot be answered, hence the InvalidOperationException. It fires when the same service type (or compatible base/interface) was registered twice.
Solutions
- Register each service under exactly one unambiguous type and query for the most specific type
- Remove the redundant registration that makes the match ambiguous
- Iterate the raw service list yourself if you truly need multiple matches
Example fix
// before provider.RegisterService(myServiceImpl); // matches IMyService and MyBase provider.RegisterService((MyBase)myServiceImpl); // ambiguous var svc = provider.TryGet(typeof(IMyService)); // throws // after provider.RegisterService(myServiceImpl); // register once var svc = provider.TryGet(typeof(IMyService));
Defensive patterns
Strategy: validation
Validate before calling
var candidates = new List<object>();
foreach (var s in services) if (serviceType.IsInstanceOfType(s)) candidates.Add(s);
if (candidates.Count > 1) throw new InvalidOperationException("Ambiguous registrations: " + serviceType.Name); Try / catch
try { svc = provider.TryGet(typeof(IMyService)); }
catch (InvalidOperationException ex) { log.Error(ex, "Ambiguous service registrations"); svc = null; } Prevention
- Register one instance per family of related types; query the most specific type
- Avoid registering both a type and its base/interface separately
- Keep the provider's parent chain free of overlapping registrations
When it happens
Trigger: Registering two services where both are instances of serviceType (e.g. one type implementing two registered interfaces, or a subclass registered alongside its base), then calling TryGet/Get for the shared type.
Common situations: Registering an interface and a base class that both match one instance; duplicate services registered under related types; parent provider + local provider ambiguities resolved in the loop before the parent fallback.
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
- No service matches the given type.
- A service of the same type has already been registered.
- No service matches the given type.
- The provided path is not a valid path name.
- Build manifest [{0}] doesn't exist
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/b9788f3d7790a7b5.
Report an issue: GitHub.
Appendix: source
Thrown at sources/presentation/Stride.Core.Presentation/ViewModels/ViewModelServiceProvider.cs:84
ArgumentNullException.ThrowIfNull(service);
if (services.Remove(service))
{
ServiceUnregistered?.Invoke(this, new ServiceRegistrationEventArgs(service));
}
}
/// <inheritdoc/>
public object? TryGet(Type serviceType)
{
ArgumentNullException.ThrowIfNull(serviceType);
object? serviceFound = null;
foreach (var service in services.Where(serviceType.IsInstanceOfType))
{
if (serviceFound != null)
throw new InvalidOperationException("Multiple services match the given type.");
serviceFound = service;
}
return serviceFound ?? parentProvider?.TryGet(serviceType);
}
/// <inheritdoc/>
public T? TryGet<T>() where T : class
{
return TryGet(typeof(T)) as T;
}
/// <inheritdoc/>
public object Get(Type serviceType)
{
var result = TryGet(serviceType);
return result ?? throw new InvalidOperationException("No service matches the given type.");View on GitHub (pinned to 96fad776d2)