{"record":{"id":"8810ed9fd6bfa155","repo":"pardeike/Harmony","slug":"cannot-find-instruction-for-offset-x4","errorCode":null,"errorMessage":"Cannot find instruction for {offset:X4}","messagePattern":"Cannot find instruction for (.+?)","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Harmony/Internal/MethodCopier.cs","lineNumber":640,"sourceCode":"\r\n\t\t\t\tif (isEndOfInstruction)\r\n\t\t\t\t{\r\n\t\t\t\t\tif (offset == instruction.offset + instruction.GetSize() - 1)\r\n\t\t\t\t\t\treturn instruction;\r\n\t\t\t\t}\r\n\t\t\t\telse\r\n\t\t\t\t{\r\n\t\t\t\t\tif (offset == instruction.offset)\r\n\t\t\t\t\t\treturn instruction;\r\n\t\t\t\t}\r\n\r\n\t\t\t\tif (offset < instruction.offset)\r\n\t\t\t\t\tmax = mid - 1;\r\n\t\t\t\telse\r\n\t\t\t\t\tmin = mid + 1;\r\n\t\t\t}\r\n\r\n\t\t\tthrow new Exception($\"Cannot find instruction for {offset:X4}\");\r\n\t\t}\r\n\r\n\t\tstatic bool TargetsLocalVariable(OpCode opcode) => opcode.Name.Contains(\"loc\");\r\n\r\n\t\tLocalVariableInfo GetLocalVariable(int index) => localVariables?[index];\r\n\r\n\t\tParameterInfo GetParameter(int index)\r\n\t\t{\r\n\t\t\tif (index == 0)\r\n\t\t\t\treturn this_parameter;\r\n\r\n\t\t\treturn parameters[index - 1];\r\n\t\t}\r\n\r\n\t\tOpCode ReadOpCode()\r\n\t\t{\r\n\t\t\tvar op = ilBytes.ReadByte();\r\n\t\t\treturn op != 0xfe\r","sourceCodeStart":622,"sourceCodeEnd":658,"githubUrl":"https://github.com/pardeike/Harmony/blob/e7872dc17008bc0ca2b3de1f53fd4120dbd7a17c/Harmony/Internal/MethodCopier.cs#L622-L658","documentation":"After the offset bounds checks pass, GetInstruction binary-searches the copied instruction list for the instruction starting at that offset. Reaching the end of the search means no instruction begins at the requested offset — i.e. an operand referenced a mid-instruction or nonexistent offset. Harmony wraps this in a plain Exception naming the offset in hex.","triggerScenarios":"IL operands pointing into the middle of an instruction (mis-decoded stream); transpilers that changed instruction sizes/positions leaving dangling branch operands; IL from obfuscated assemblies that the linear reader cannot map correctly.","commonSituations":"Transpiling obfuscated game code; custom transpilers that mutate operand values to raw offsets instead of labels; edge-case IL patterns on older Mono/JIT implementations.","solutions":["Rewrite transpilers to manipulate instructions via labels and CodeInstruction objects, never by setting raw integer offsets into operands","Test the same patch against an unobfuscated build to confirm obfuscation is the cause","Bisect which transpiler/method combination triggers it and file a Harmony issue with the IL if it looks like a reader bug","Update Harmony to the latest version — IL decoding bugs are periodically fixed"],"exampleFix":"// before\nci.operand = 0x0012; // raw offset, no matching instruction\n// after\nvar target = instructions.First(i => i.offset == 0x0012 || i.labels.Any());\nvar lbl = generator.DefineLabel();\ntarget.labels.Add(lbl);\nci.operand = lbl;","handlingStrategy":"try-catch","validationCode":"// smoke-test the full patch pipeline at startup for every transpiled target\nforeach (var t in targets) { try { new PatchProcessor(t).AddTranspiler(tr).Patch(); } catch (Exception e) { Log.Error($\"{t}: {e.Message}\"); } }","typeGuard":null,"tryCatchPattern":"try { harmony.Patch(target, transpiler: trans); }\ncatch (Exception ex) when (ex.Message.StartsWith(\"Cannot find instruction for\"))\n{ Log.Error($\"IL mapping failed for {target}: {ex.Message}\"); }","preventionTips":["Use CodeInstruction labels for all branch manipulation; never assign raw offsets to operand","Do not mutate the operands of copied instructions that reference fixed offsets","Verify patches on an unobfuscated build to isolate obfuscation-induced IL weirdness","Report reproducible vanilla-IL failures to the Harmony issue tracker"],"tags":["harmony","il","instruction-lookup"],"backgroundTag":"internal-invariant-violation","analyzedSha":"e7872dc17008bc0ca2b3de1f53fd4120dbd7a17c","analyzedAt":"2026-09-15T22:47:11.550Z","contentChangedAt":"2026-09-15T22:47:11.550Z","schemaVersion":2},"datasetVersion":"2026-09-16T09:17:16.951Z"}