{"record":{"id":"507af33f76cccfab","repo":"egametang/ET","slug":"none-of-methods-targetmethod-or-replacementmethod","errorCode":null,"errorMessage":"none of methods targetMethod or replacementMethod can be null","messagePattern":"none of methods targetMethod or replacementMethod can be null","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"Packages/cn.etetet.hybridclr/Scripts/Editor/Share/3rds/UnityHook/MethodHook.cs","lineNumber":155,"sourceCode":"            isPlayModeHook = Application.isPlaying;\n        }\n\n        public void Uninstall()\n        {\n            if (!isHooked)\n                return;\n\n            _codePatcher.RemovePatch();\n\n            isHooked = false;\n            HookPool.RemoveHooker(targetMethod);\n        }\n\n        #region private\n        private void DoInstall()\n        {\n            if (targetMethod == null || replacementMethod == null)\n                throw new Exception(\"none of methods targetMethod or replacementMethod can be null\");\n\n            HookPool.AddHook(targetMethod, this);\n\n            if (_codePatcher == null)\n            {\n                if (GetFunctionAddr())\n                {\n#if ENABLE_HOOK_DEBUG\n                    UnityEngine.Debug.Log($\"Original [{targetMethod.DeclaringType.Name}.{targetMethod.Name}]: {HookUtils.HexToString(_targetPtr.ToPointer(), 64, -16)}\");\n                    UnityEngine.Debug.Log($\"Original [{replacementMethod.DeclaringType.Name}.{replacementMethod.Name}]: {HookUtils.HexToString(_replacementPtr.ToPointer(), 64, -16)}\");\n                    if(proxyMethod != null)\n                        UnityEngine.Debug.Log($\"Original [{proxyMethod.DeclaringType.Name}.{proxyMethod.Name}]: {HookUtils.HexToString(_proxyPtr.ToPointer(), 64, -16)}\");\n#endif\n\n                    CreateCodePatcher();\n                    _codePatcher.ApplyPatch();\n\n#if ENABLE_HOOK_DEBUG","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.hybridclr/Scripts/Editor/Share/3rds/UnityHook/MethodHook.cs#L137-L173","documentation":"Thrown by MethodHook.DoInstall() when either targetMethod or replacementMethod is null. DoInstall is the core hook-installation entry point; it needs valid MethodInfo objects for both the original method (to patch) and the replacement method (to jump to). A null means the caller failed to resolve one via reflection before constructing the hook.","triggerScenarios":"Calling Install() on a MethodHook instance where the targetMethod or replacementMethod field is null. This typically stems from a reflection lookup (GetMethod, Type.GetMethod) that returned null — e.g. the method name was misspelled, the binding flags were wrong, the method is overloaded and the signature didn't match, or the declaring type wasn't loaded.","commonSituations":"The target method was renamed or removed in a library update; BindingFlags mismatch when calling GetMethod on a non-public or static method; an overloaded method where the overload resolution via reflection returned null; the assembly containing the target type wasn't loaded yet at hook construction time.","solutions":["Log both targetMethod and replacementMethod before calling Install() to identify which is null.","Fix the reflection lookup: verify the method name, declaring type, binding flags, and parameter signature match exactly.","If the method was renamed in an update, update the hook code to use the new name.","Ensure the assembly containing the target type is loaded before constructing the MethodHook — call Assembly.Load or trigger type resolution first."],"exampleFix":"// before\nvar hook = new MethodHook(targetMethod, replacementMethod);\nhook.Install(); // throws if targetMethod is null\n\n// after — validate before installing\nif (targetMethod == null)\n    Debug.LogError($\"Target method not found on type {targetType.FullName}\");\nif (replacementMethod == null)\n    Debug.LogError($\"Replacement method not found on type {replacementType.FullName}\");\nif (targetMethod != null && replacementMethod != null)\n{\n    var hook = new MethodHook(targetMethod, replacementMethod);\n    hook.Install();\n}","handlingStrategy":"validation","validationCode":"if (targetMethod == null)\n    Debug.LogError($\"Target method not found. Check type '{targetTypeName}' and method name '{targetMethodName}' with correct BindingFlags.\");\nif (replacementMethod == null)\n    Debug.LogError($\"Replacement method not found. Check type '{replacementTypeName}' and method name '{replacementMethodName}'.\");\nif (targetMethod == null || replacementMethod == null)\n    return; // do not proceed to Install()","typeGuard":"static bool IsHookable(MethodInfo target, MethodInfo replacement)\n{\n    return target != null && replacement != null && !target.IsAbstract;\n}","tryCatchPattern":"try\n{\n    hook.Install();\n}\ncatch (Exception ex) when (ex.Message.Contains(\"none of methods targetMethod or replacementMethod can be null\"))\n{\n    Debug.LogError($\"Hook installation failed: targetMethod={targetMethod?.Name ?? \"null\"}, \" +\n        $\"replacementMethod={replacementMethod?.Name ?? \"null\"}. \" +\n        \"Verify reflection lookups (method name, BindingFlags, overload signature).\");\n}","preventionTips":["Always null-check MethodInfo results from GetMethod before constructing a MethodHook.","Use precise BindingFlags (Public/NonPublic, Static/Instance) matching the target method.","For overloaded methods, use the GetMethod overload that accepts parameter types to avoid ambiguity.","Ensure the declaring type's assembly is loaded before reflection."],"tags":["unityhook","method-hook","reflection","null-reference","installation"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}