egametang/ET · error · Exception
[PreservedMethod] method:{method} has generic parameters
Error message
[PreservedMethod] method:{method} has generic parameters What it means
Thrown by Generator.ProcessMethod when a method has HasGenericParameters == true and there is no class or method instantiation (klassInst == null and methodInst == null). ProcessMethod handles both instantiated and non-instantiated methods; for the non-instantiated path it requires the method to be non-generic, because an open generic method has no concrete signature to bridge.
Source
Thrown at Packages/cn.etetet.hybridclr/Scripts/Editor/Share/MethodBridge/Generator.cs:205
if (method.IsPrivate || (method.IsAssembly && !method.IsPublic && !method.IsFamily))
{
if (klassInst == null && methodInst == null)
{
return;
}
else
{
//Debug.Log($"[PreservedMethod] method:{method}");
}
}
ICorLibTypes corLibTypes = method.Module.CorLibTypes;
TypeSig returnType;
List<TypeSig> parameters;
if (klassInst == null && methodInst == null)
{
if (method.HasGenericParameters)
{
throw new Exception($"[PreservedMethod] method:{method} has generic parameters");
}
returnType = MetaUtil.ToShareTypeSig(corLibTypes, method.ReturnType);
parameters = method.Parameters.Select(p => MetaUtil.ToShareTypeSig(corLibTypes, p.Type)).ToList();
}
else
{
var gc = new GenericArgumentContext(klassInst, methodInst);
returnType = MetaUtil.ToShareTypeSig(corLibTypes, MetaUtil.Inflate(method.ReturnType, gc));
parameters = method.Parameters.Select(p => MetaUtil.ToShareTypeSig(corLibTypes, MetaUtil.Inflate(p.Type, gc))).ToList();
}
var m2nMethod = CreateMethodDesc(method, false, returnType, parameters);
AddManaged2NativeMethod(m2nMethod);
if (method.IsVirtual)
{
if (method.DeclaringType.IsInterface)
{View on GitHub (pinned to 5cab01f7a8)
Solutions
- Run HybridCLR/Generate/AOTGenericReference so all generic instantiations are collected and ProcessMethod receives concrete klassInst/methodInst.
- If the method should never be bridged generically, remove it from preserved/reverse-P/Invoke targets.
- Refactor the method to be non-generic or ensure every call site uses explicit concrete type arguments that the collector can see.
- Re-run HybridCLR/Generate/All after collecting instantiations.
Defensive patterns
Strategy: validation
Validate before calling
// In ProcessMethod: guard the non-instantiated path
if (klassInst == null && methodInst == null && method.HasGenericParameters)
Debug.LogError("Method is generic with no instantiation -- cannot bridge."); Prevention
- Collect all generic instantiations via AOTGenericReference before bridge generation.
- Do not register open generic methods as reverse-P/Invoke or preserved targets.
- Ensure every generic call site uses explicit concrete type arguments visible to the collector.
When it happens
Trigger: ProcessMethod(method, klassInst=null, methodInst=null) is reached for a method that is referenced as a preserved/bridge target without a concrete instantiation, and method.HasGenericParameters is true. The code throws before computing returnType/parameters.
Common situations: A generic method is referenced (e.g. via MonoPInvokeCallback or a preserved list) without specifying type arguments; the generic reference collector did not record the instantiation; a new generic method was added to a type that participates in reverse P/Invoke.
Related errors
- [PreservedMethod] method:{methodDef} has generic parameters
- [PreservedMethod] method has generic parameters
- no aot assembly found. please run `HybridCLR/Generate/All` o
- type:{typeSig} definition could not be found. Please try `Hy
- type:{type} definition could not be found. Please try `Hybri
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/7076c04669a0b2c0.
Report an issue: GitHub.