pardeike/Harmony · error · Exception
Wrong null argument
Error message
Wrong null argument: {codeInstruction} What it means
During EmitCodes, an instruction with an InlineSig operand type (a calli signature) arrived with a null operand. Harmony's emitter cannot pass a null call-site signature to the underlying emitter, so this indicates malformed/corrupted IL in the transpiled instruction list.
Solutions
- Find the transpiler producing the calli instruction and set its operand to a valid signature (ILGenerator-compatible SignatureHelper/ICallSiteGenerator).
- Remove or replace the null-operand calli instruction in the transpiled list.
- Dump the transpiled instructions (Harmony.DEBUG logging) to locate the offending instruction.
Example fix
// before yield return new CodeInstruction(OpCodes.Calli, null); // after yield return new CodeInstruction(OpCodes.Calli, signatureHelper); // valid ICallSiteGenerator operand
Defensive patterns
Strategy: type-guard
Validate before calling
foreach (var ci in transpiledInstructions)
if (ci.opcode.OperandType == OperandType.InlineSig && ci.operand is null)
throw new InvalidOperationException("calli instruction without signature"); Type guard
static bool HasValidSigOperand(CodeInstruction ci) =>
ci.opcode.OperandType != OperandType.InlineSig || ci.operand is ICallSiteGenerator; Try / catch
try { harmony.Patch(original, transpiler: t); }
catch (Exception ex) when (ex.Message.StartsWith("Wrong null argument"))
{ Logger.Error($"Transpiler emitted calli with null operand: {ex.Message}"); } Prevention
- Never construct calli instructions by hand; copy both opcode and operand when cloning.
- Test transpilers with Harmony.DEBUG to dump emitted IL before shipping.
- Avoid manipulating raw calli sites unless you fully rebuild the signature.
When it happens
Trigger: A transpiler emits an Instruction whose opcode is calli (InlineSig) but sets operand to null, or an IL manipulation step stripped the signature operand before EmitCodes runs.
Common situations: Custom transpilers that copy instructions but forget the operand, IL manipulation libraries (e.g. manual Cecil-style edits) producing calli without a signature, or hand-built CodeInstruction lists.
Related errors
- Wrong Emit argument type
- Unbalanced exception markers – cannot rewrite.
- Value cannot be null. (Parameter 'generator')
- Cannot create replacement for
- Unexpected null argument
AI-assisted analysis of pardeike/Harmony@e7872dc170 (2026-09-15).
Data as JSON: /api/errors/0a825b15997e2b6a.
Report an issue: GitHub.
Appendix: source
Thrown at Harmony/Internal/MethodCreatorTools.cs:634
// mark all labels
codeInstruction.labels.Do(label => emitter.MarkLabel(label));
// start all exception blocks
codeInstruction.blocks.Do(block => emitter.MarkBlockBefore(block, out var _));
var code = codeInstruction.opcode;
var operand = codeInstruction.operand;
switch (code.OperandType)
{
case OperandType.InlineNone:
if (codeInstruction.IsAnnotation() == null)
emitter.Emit(code);
break;
case OperandType.InlineSig:
if (operand is null)
throw new Exception($"Wrong null argument: {codeInstruction}");
if ((operand is ICallSiteGenerator) is false)
throw new Exception($"Wrong Emit argument type {operand.GetType()} in {codeInstruction}");
emitter.Emit(code, (ICallSiteGenerator)operand);
break;
default:
if (operand is null)
throw new Exception($"Wrong null argument: {codeInstruction}");
emitter.DynEmit(code, operand);
break;
}
codeInstruction.blocks.Do(block => emitter.MarkBlockAfter(block));
});
}
static List<CodeInstruction> InitializeOutParameter(int argIndex, Type type)
{
View on GitHub (pinned to e7872dc170)