egametang/ET · error · Exception
[PreservedMethod] method:{methodDef} has generic parameters
Error message
[PreservedMethod] method:{methodDef} has generic parameters What it means
Thrown by Generator.CreateMethodDesc (the overload taking a MethodDef) when the method's return type ContainsGenericParameter. The method bridge generator requires fully concrete type signatures to emit bridge/wrapper functions; an open generic parameter on the return type means the signature was never inflated to a concrete type.
Source
Thrown at Packages/cn.etetet.hybridclr/Scripts/Editor/Share/MethodBridge/Generator.cs:124
string sigName = ToFullName(typeInfo.Klass);
if (!_sig2Types.TryGetValue(sigName, out var sharedTypeInfo))
{
sharedTypeInfo = typeInfo;
_sig2Types.Add(sigName, sharedTypeInfo);
}
return sharedTypeInfo;
}
private MethodDesc CreateMethodDesc(MethodDef methodDef, bool forceRemoveThis, TypeSig returnType, List<TypeSig> parameters)
{
var paramInfos = new List<ParamInfo>();
if (forceRemoveThis && !methodDef.IsStatic)
{
parameters.RemoveAt(0);
}
if (returnType.ContainsGenericParameter)
{
throw new Exception($"[PreservedMethod] method:{methodDef} has generic parameters");
}
foreach (var paramInfo in parameters)
{
if (paramInfo.ContainsGenericParameter)
{
throw new Exception($"[PreservedMethod] method:{methodDef} has generic parameters");
}
paramInfos.Add(new ParamInfo() { Type = GetSharedTypeInfo(paramInfo) });
}
var mbs = new MethodDesc()
{
MethodDef = methodDef,
ReturnInfo = new ReturnInfo() { Type = returnType != null ? GetSharedTypeInfo(returnType) : TypeInfo.s_void },
ParamInfos = paramInfos,
};
return mbs;
}
View on GitHub (pinned to 5cab01f7a8)
Solutions
- Ensure all generic method instantiations used across the AOT/hot-update boundary are captured by HybridCLR/Generate/AOTGenericReference first.
- If a method is annotated [PreservedMethod] or [MonoPInvokeCallback], make sure it is non-generic or only used with concrete instantiations.
- Re-run HybridCLR/Generate/All to regenerate bridge functions with the latest generic reference data.
- Inspect the methodDef printed in the exception and refactor it to avoid open generic parameters at the bridge boundary.
Defensive patterns
Strategy: validation
Validate before calling
// Before bridge generation, ensure no preserved method has open generics
if (returnType.ContainsGenericParameter)
Debug.LogError("Method return type has open generic -- inflate or avoid bridging."); Prevention
- Run AOTGenericReference generation before MethodBridge so all instantiations are known.
- Avoid annotating generic methods with [PreservedMethod] / [MonoPInvokeCallback].
- Review new generic APIs added at the managed/native boundary.
When it happens
Trigger: CreateMethodDesc(methodDef, forceRemoveThis, returnType, parameters) is called with a returnType whose ContainsGenericParameter is true. This happens when ProcessMethod passed through a method whose generic arguments were not substituted (klassInst/methodInst both null but the method still carries open generics).
Common situations: A preserved method (annotated or referenced via reverse P/Invoke) is itself generic and was not instantiated before bridge generation; the AOT generic reference pass missed an instantiation; a code change introduced a generic method signature that HybridCLR cannot bridge.
Related errors
- [PreservedMethod] method has generic parameters
- [PreservedMethod] method:{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/78505b2ad4a70008.
Report an issue: GitHub.