{"record":{"id":"a15f02cec50fc259","repo":"PrismLibrary/Prism","slug":"could-not-find-invoke-method-for-delegate-of-type","errorCode":null,"errorMessage":"Could not find Invoke() method for delegate of type {multicastDelegate.GetType().Name}","messagePattern":"Could not find Invoke\\(\\) method for delegate of type (.+?)","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Prism.Core/Common/MulticastExceptionHandler.cs","lineNumber":66,"sourceCode":"        await HandleAsync(exception, parameter);\n\n    /// <summary>\n    /// Handles a specified <see cref=\"Exception\"/> asynchronously with a given optional parameter\n    /// </summary>\n    /// <param name=\"exception\">The <see cref=\"Exception\"/> encountered.</param>\n    /// <param name=\"parameter\">An optional parameter which may be passed to a registered callback delegate.</param>\n    /// <returns>An asynchronus Task.</returns>\n    /// <exception cref=\"InvalidOperationException\"></exception>\n    public async Task HandleAsync(Exception exception, object? parameter = null)\n    {\n        var multicastDelegate = GetDelegate(exception.GetType());\n\n        if (multicastDelegate is null)\n            return;\n\n        // Get Invoke() method of the delegate\n        var invokeMethod = multicastDelegate.GetType().GetMethod(\"Invoke\")\n            ?? throw new InvalidOperationException($\"Could not find Invoke() method for delegate of type {multicastDelegate.GetType().Name}\");\n\n        var parameters = invokeMethod.GetParameters();\n        var arguments = parameters.Length switch\n        {\n            0 => Array.Empty<object?>(),\n            1 => typeof(Exception).IsAssignableFrom(parameters[0].ParameterType) ? [exception] : [parameter],\n            2 => typeof(Exception).IsAssignableFrom(parameters[0].ParameterType) ? [exception, parameter] : [parameter, exception],\n            _ => throw new InvalidOperationException($\"Handler of type {multicastDelegate.GetType().Name} is not supported\", exception)\n        };\n\n        // Invoke the delegate\n        var result = invokeMethod.Invoke(multicastDelegate, arguments);\n\n        // If the handler is async (returns a Task), then we await the task\n        if (result is Task task)\n        {\n            await task;\n        }","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/PrismLibrary/Prism/blob/358118cd640d9a22ff8cf21c8ad197fa038b7990/src/Prism.Core/Common/MulticastExceptionHandler.cs#L48-L84","documentation":"MulticastExceptionHandler.HandleAsync resolves the delegate's Invoke method via reflection; if it cannot be found it throws InvalidOperationException. This indicates a delegate type whose Invoke method is not visible via GetMethod, which should never happen for real delegates, so it signals an internal invariant violation or an exotic dynamic proxy type.","triggerScenarios":"Passing a synthetic/proxy object cast to MulticastDelegate whose GetMethod(\"Invoke\") returns null (e.g. certain mocking proxies or dynamically generated types lacking a public Invoke).","commonSituations":"Registering mocked exception handlers in unit tests with mocking frameworks that generate delegate-like proxies instead of true delegates.","solutions":["Pass a real C# delegate (Action, Func, or custom delegate type)","Avoid wrapping handlers in reflection-generated proxies","If mocking, create a true delegate instead of a proxy object","Catch InvalidOperationException around handler registration and log the delegate type"],"exampleFix":"// before\nobject fakeHandler = mockProxy; // not a real delegate\nexceptionHandler.Handle(exception, fakeHandler);\n// after\nExceptionHandledDelegate handler = (e, p) => Task.CompletedTask;\nexceptionHandler.Handle(exception, handler);","handlingStrategy":"try-catch","validationCode":"var invoke = multicastDelegate?.GetType().GetMethod(\"Invoke\");\nif (invoke is null) throw new InvalidOperationException(\"Delegate has no Invoke method\");","typeGuard":"bool isUsableDelegate(object d) => d is MulticastDelegate && d.GetType().GetMethod(\"Invoke\") is not null;","tryCatchPattern":"try { exceptionHandler.Handle(exception, handler); }\ncatch (InvalidOperationException ex) { logger.LogError(ex, \"Handler delegate unusable: {Type}\", handler.GetType().Name); }","preventionTips":["Use only genuine delegates as exception handlers","Avoid proxy/mocked objects in handler slots","Unit-test handler registration with real delegate types"],"tags":["reflection","delegate","prism","internal"],"backgroundTag":"internal-invariant-violation","analyzedSha":"358118cd640d9a22ff8cf21c8ad197fa038b7990","analyzedAt":"2026-09-15T15:00:31.079Z","contentChangedAt":"2026-09-15T15:00:31.079Z","schemaVersion":2},"datasetVersion":"2026-09-16T04:17:20.429Z"}