dotnet/machinelearning · error · ArgumentException
Did not find access modifier (Parameter 'constructorInfo')
Error message
Did not find access modifier (Parameter 'constructorInfo')
What it means
The Accessmodifier extension on ConstructorInfo mirrors the MethodInfo version: it classifies constructor visibility into the AccessModifier enum and throws ArgumentException('Did not find access modifier', nameof(constructorInfo)) if no visibility flag matches. ComponentCatalog invokes it when enumerating registrable constructors.
Solutions
- Only register statically compiled, normal CLR types with ComponentCatalog.
- Check the target constructor's visibility flags via reflection before registration and skip non-standard ones.
- Catch ArgumentException during registration and log/skip the offending type.
- Rebuild the component assembly if its metadata appears corrupted.
Example fix
// before
catalog.RegisterComponent(typeof(DynamicProxy));
// after
var ctors = typeof(DynamicProxy).GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
if (ctors.All(c => c.IsPublic || c.IsPrivate || c.IsFamily || c.IsAssembly || c.IsFamilyOrAssembly))
catalog.RegisterComponent(typeof(DynamicProxy)); Defensive patterns
Strategy: validation
Validate before calling
var c = typeof(MyComponent).GetConstructor(new[]{ typeof(MLContext) });
bool classifiable = c.IsPublic || c.IsPrivate || c.IsFamily ||
c.IsAssembly || c.IsFamilyOrAssembly || c.IsFamilyAndAssembly;
if (!classifiable) throw new InvalidOperationException("Constructor visibility non-standard"); Type guard
static bool HasStandardCtorVisibility(ConstructorInfo c) =>
c.IsPublic || c.IsPrivate || c.IsFamily ||
c.IsAssembly || c.IsFamilyOrAssembly || c.IsFamilyAndAssembly; Try / catch
try
{
catalog.RegisterComponent(type);
}
catch (ArgumentException ex) when (ex.ParamName == "constructorInfo")
{
logger.LogWarning($"Skipped {type}: non-standard constructor visibility");
} Prevention
- Use ordinary public or internal constructors on registered component types.
- Avoid registering dynamically emitted types.
- Pre-screen constructors with the visibility-flag check before registration.
- Rebuild assemblies if reflection metadata looks inconsistent.
When it happens
Trigger: ComponentCatalog enumerating constructors of a registered type and encountering a ConstructorInfo with none of the standard visibility flags — typically only from dynamically emitted constructors or non-standard compiler output.
Common situations: Registering types from Reflection.Emit-generated assemblies; duplicate/corrupted assembly versions where the reflected constructor metadata is malformed.
Understand the failure class
Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.
Related errors
- Did not find access modifier (Parameter 'methodInfo')
- Type IPredictionTransformer not implemented by provided type
- Bad data kind in ColumnTypeExtensions.NumberTypeFromKind
- Bad type in ColumnTypeExtensions.NumberTypeFromType
- Cannot set parameter
AI-assisted analysis of dotnet/machinelearning@7b76e69cf9 (2026-09-11).
Data as JSON: /api/errors/10c5b1e9f68ec04c.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.ML.Core/ComponentModel/ComponentCatalog.cs:50
return AccessModifier.Public;
throw new ArgumentException("Did not find access modifier", nameof(methodInfo));
}
internal static AccessModifier Accessmodifier(this ConstructorInfo constructorInfo)
{
if (constructorInfo.IsFamilyAndAssembly)
return AccessModifier.PrivateProtected;
if (constructorInfo.IsPrivate)
return AccessModifier.Private;
if (constructorInfo.IsFamily)
return AccessModifier.Protected;
if (constructorInfo.IsFamilyOrAssembly)
return AccessModifier.ProtectedInternal;
if (constructorInfo.IsAssembly)
return AccessModifier.Internal;
if (constructorInfo.IsPublic)
return AccessModifier.Public;
throw new ArgumentException("Did not find access modifier", nameof(constructorInfo));
}
internal enum AccessModifier
{
PrivateProtected,
Private,
Protected,
ProtectedInternal,
Internal,
Public
}
}
/// <summary>
/// This catalogs instantiable components (aka, loadable classes). Components are registered via
/// a descendant of <see cref="LoadableClassAttributeBase"/>, identifying the names and signature types under which the component
/// type should be registered. Signatures are delegate types that return void and specify that parameter
/// types for component instantiation. Each component may also specify an "arguments object" that shouldView on GitHub (pinned to 7b76e69cf9)