devlooped/moq · error · ArgumentException
Type does not implement required interface
Error message
Type {0} does not implement required interface {1} What it means
Guard.ImplementsInterface verifies that a given type actually implements the interface required by the operation before proceeding. When interfaceType.IsAssignableFrom(type) is false, Moq throws ArgumentException naming both the type and the missing interface. It prevents later invalid casts or mock misconfiguration.
Solutions
- Make the type implement the required interface (add `: IRequired` and members).
- Pass a type that actually implements the interface.
- Fix the interface name/generic argument if you passed the wrong one.
- Check for version mismatches where the interface moved to a different assembly/namespace.
Example fix
// before
Guard.ImplementsInstance(typeof(Service), paramName, typeof(IRepo)); // Service does not implement IRepo
class Service { }
// after
class Service : IRepo { public Thing Get(int id) => ...; } Defensive patterns
Strategy: type-guard
Validate before calling
if (!typeof(IRequired).IsAssignableFrom(typeof(Service))) throw new InvalidOperationException($"{typeof(Service).Name} must implement {nameof(IRequired)}"); Type guard
bool Implements<TInterface>(Type t) where TInterface : class => typeof(TInterface).IsAssignableFrom(t);
Try / catch
try { Guard.ImplementsInstance(serviceType, nameof(serviceType), typeof(IRepo)); }
catch (ArgumentException ex) when (ex.Message.Contains("does not implement required interface")) { /* fix the type or registration */ throw; } Prevention
- Add compile-time constraints (where T : IRepo) so mismatches fail at compile time.
- Run a reflection-based startup test asserting service registrations implement their interfaces.
- Re-check interface implementations after renaming/refactoring interfaces.
When it happens
Trigger: Registering or wiring a type where an interface is required — e.g. passing a service type to a mock/proxy factory, mock.As<TInterface> with an incompatible type, or generic APIs guarded by this check with a mismatched type argument.
Common situations: Refactoring renamed or removed an interface implementation; a DI/mock configuration registers a concrete type that no longer implements the declared interface; wrong generic type argument supplied to setup helpers.
Understand the failure class
Background: Type mismatch errors: IllegalArgumentException, TypeError and type guards across 150 open-source libraries — this error's family across 150 libraries.
Related errors
- Resources.ConstructorArgsForInterface
- Unsupported expression
- Could not determine the correct positions for all argument…
- The return type of the last member shown above is not…
- Value cannot be null. (Parameter 'value')
AI-assisted analysis of devlooped/moq@89a5be629c (2026-09-16).
Data as JSON: /api/errors/56f2ba14d9c5124d.
Report an issue: GitHub.
Appendix: source
Thrown at src/Moq/Guard.cs:41
{
throw new ArgumentException(
string.Format(
CultureInfo.CurrentCulture,
Resources.TypeHasNoDefaultConstructor,
type.GetFormattedName()));
}
}
public static void ImplementsInterface(Type interfaceType, Type type, string? paramName = null)
{
Debug.Assert(interfaceType != null);
Debug.Assert(interfaceType.IsInterface);
Debug.Assert(type != null);
if (interfaceType.IsAssignableFrom(type) == false)
{
throw new ArgumentException(
string.Format(
CultureInfo.CurrentCulture,
Resources.TypeNotImplementInterface,
type.GetFormattedName(),
interfaceType.GetFormattedName()),
paramName);
}
}
public static void ImplementsTypeMatcherProtocol(Type type)
{
Debug.Assert(type != null);
Guard.ImplementsInterface(typeof(ITypeMatcher), type);
Guard.CanCreateInstance(type);
}
public static void IsAssignmentToPropertyOrIndexer(LambdaExpression expression, string paramName)View on GitHub (pinned to 89a5be629c)