pardeike/Harmony · error · ArgumentException
Can not get IL bytes of method
Error message
Can not get IL bytes of method {method.FullDescription()} What it means
MethodBodyReader asks the runtime for the method's IL as a byte array (MethodBase.GetMethodBody().GetILAsByteArray()) and throws if the bytes are null. This happens for methods that have no IL body at all — abstract methods, extern/P-Invoke methods, runtime-intrinsic methods, or methods implemented natively. Harmony cannot copy or transpile a method that has no IL.
Solutions
- Patch the concrete implementation (derived type's override) instead of the abstract/interface method
- Do not attempt to patch extern/P-Invoke/native methods; patch a managed caller instead or use a different hooking technique
- Check method.IsAbstract / method.GetMethodBody() == null before patching and skip or warn
- For interface contracts, patch all concrete implementations or use a proxy/dispatcher pattern
Example fix
// before
var m = typeof(IFoo).GetMethod("Bar"); // abstract - no IL
harmony.Patch(m, transpiler: trans);
// after
var m = typeof(FooImpl).GetMethod("Bar"); // concrete override with IL body
if (m.GetMethodBody() != null)
harmony.Patch(m, transpiler: trans); Defensive patterns
Strategy: validation
Validate before calling
bool CanPatch(MethodBase m) => m is not null && !m.IsAbstract && !m.IsVirtual || (m.IsVirtual && m.GetMethodBody() is not null);
// safer: check body directly
bool HasIl(MethodBase m) => m?.GetMethodBody()?.GetILAsByteArray() is { Length: > 0 }; Type guard
static bool IsPatchable(MethodBase m) =>
m is MethodInfo mi && mi.GetMethodBody() != null; Try / catch
try { harmony.Patch(target, transpiler: trans); }
catch (ArgumentException ex) when (ex.Message.Contains("Can not get IL bytes"))
{ Log.Warn($"{target.FullDescription()} has no IL body (abstract/extern/native) — skipping"); } Prevention
- Never target abstract, interface, or extern/P-Invoke methods; patch concrete implementations or managed callers
- Check GetMethodBody() != null before transpiling
- On IL2CPP/AOT, verify the method is actually JIT-compiled IL before patching
- Prefer patching a managed wrapper over native internal-call methods
When it happens
Trigger: Attempting to Patch() or reverse-patch an abstract or interface method; patching an extern or P/Invoke (DllImport) method; patching methods with MethodImplAttributes like AggressiveInlining + native/runtime on some runtimes; patching into a Mono/runtime where GetMethodBody returns null for the target.
Common situations: Trying to transpile interface or abstract methods instead of the concrete implementation; patching native methods (UnityEngine internal calls) which have no CIL body; targeting a property accessor that is abstract; AOT/IL2CPP environments where JIT IL bodies are unavailable.
Understand the failure class
Background: UnsupportedOperationException and "is not supported" errors: when a library deliberately refuses a call — this error's family across 30 libraries.
Related errors
- The type must declare an empty constructor (the constructor…
- Instruction offset is less than 0
- Instruction offset is outside valid range 0
- Cannot find instruction for
- Unexpected null argument
AI-assisted analysis of pardeike/Harmony@e7872dc170 (2026-09-15).
Data as JSON: /api/errors/11d5639715742a24.
Report an issue: GitHub.
Appendix: source
Thrown at Harmony/Internal/MethodCopier.cs:107
}
internal MethodBodyReader(MethodBase method, ILGenerator generator)
{
this.generator = generator;
this.method = method;
module = method.Module;
var body = method.GetMethodBody();
if ((body?.GetILAsByteArray()?.Length ?? 0) == 0)
{
ilBytes = new ByteBuffer([]);
ilInstructions = [];
}
else
{
var bytes = body.GetILAsByteArray();
if (bytes is null)
throw new ArgumentException("Can not get IL bytes of method " + method.FullDescription());
ilBytes = new ByteBuffer(bytes);
ilInstructions = new List<ILInstruction>((bytes.Length + 1) / 2);
}
var type = method.DeclaringType;
if (type is not null && type.IsGenericType)
{
try
{ typeArguments = type.GetGenericArguments(); }
catch { typeArguments = null; }
}
if (method.IsGenericMethod)
{
try
{ methodArguments = method.GetGenericArguments(); }
catch { methodArguments = null; }
View on GitHub (pinned to e7872dc170)