System.Reflection.TargetInvocationException
A TargetInvocationException is thrown when a method that was called with reflection throws an exception. The reflection call wraps the real exception, and the message is always Exception has been thrown by the target of an invocation, which tells you nothing about the cause.
The cause is in InnerException. It is the same kind of wrapper as the TypeInitializationException: the outer exception is never the problem, the inner one is.
Minimum version: >= 1.1 >= Core 1.0
Statistics
Common causes
The exception means that you called something indirectly, and that code threw. These are the usual ways to end up here.
MethodInfo.Invoke on a method that throws
Plugin systems, test frameworks, serializers and anything that finds methods by name use MethodInfo.Invoke. If the method throws, you get the wrapper, not the exception from the method.
public class Plugin
{
public void Run() => throw new InvalidOperationException("Plugin is not configured");
}
Ask the runtime not to wrap the exception, with BindingFlags.DoNotWrapExceptions. The caller then gets the original type:
public class Plugin
{
public void Run() => throw new InvalidOperationException("Plugin is not configured");
}
A constructor that throws inside Activator.CreateInstance
Objects that are created with reflection, by Activator.CreateInstance, by a dependency injection container or by a plugin loader, wrap the exception from their constructor.
public class Repository
{
public Repository() => throw new InvalidOperationException("Connection string is missing");
}
Catch the wrapper where the object is created, and use the inner exception:
public class Repository
{
public Repository() => throw new InvalidOperationException("Connection string is missing");
}
Delegate.DynamicInvoke
DynamicInvoke calls a delegate without knowing its type, and wraps the exception the same way as reflection does. A normal call does not.
Action action = () => throw new InvalidOperationException("Failed");
action.DynamicInvoke(); // TargetInvocationException
Call the delegate directly when you can. It is faster, and throws the original exception:
Action action = () => throw new InvalidOperationException("Failed");
action();
How to fix it and prevent it
Always look at the InnerException
Make logging include it. The elmah.io client and most loggers do, but a message that only uses e.Message has nothing useful. GetBaseException() returns the innermost exception.
Rethrow the inner exception without losing its trace
If you want callers to see the original exception, rethrow it with ExceptionDispatchInfo. It keeps the stack trace of the inner exception, which throw e.InnerException does not.
public void Run(System.Reflection.MethodInfo method, object target)
{
try
{
method.Invoke(target, null);
}
catch (System.Reflection.TargetInvocationException e) when (e.InnerException is not null)
{
System.Runtime.ExceptionServices.ExceptionDispatchInfo.Capture(e.InnerException).Throw();
}
}
Avoid reflection when you can
Interfaces, generics and delegates give you the call without reflection, so the compiler checks it and the exceptions are not wrapped. Use reflection for what can only be found at run time.
How to read the stack trace
The outer trace shows the reflection call. The inner exception is the real failure, and its trace starts in the code that threw:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation.
---> System.InvalidOperationException: Plugin is not configured
at Shop.Services.PluginHost.Boom() in C:\src\Shop\Plugins\Plugin.cs:line 30
at System.Reflection.MethodBaseInvoker.InterpretedInvoke_Method(Object obj, IntPtr* args)
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
--- End of inner exception stack trace ---
at System.Reflection.MethodBaseInvoker.InvokeWithNoArgs(Object obj, BindingFlags invokeAttr)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Reflection.MethodBase.Invoke(Object obj, Object[] parameters)
at Shop.Services.PluginHost.Run() in C:\src\Shop\Services\PluginHost.cs:line 12
at Program.<Main>$(String[] args) in C:\src\Shop\Program.cs:line 4
The inner exception is an InvalidOperationException with the message Plugin is not configured, thrown on line 30 of Plugin.cs. The frames from System.Reflection are only the call through reflection, and PluginHost.Run on line 12 is the code that invoked the method. Fix the plugin, not the host.
Should you catch it?
Catch it where you call through reflection, and handle the InnerException. Nothing else in the application should have to know about the wrapper.
Do not catch it only to log the outer message. The outer message is the same every time, and the information that you need is on the inner exception.
Find TargetInvocationException before your users do
elmah.io logs every unhandled exception in your .NET application with its stack trace and request details, groups identical errors and notifies you when a new one appears.
Start free trialRelated exceptions
- MissingMethodException is thrown when a method is not found by reflection.
- TypeInitializationException is another wrapper, for exceptions in static constructors.
- AggregateException wraps exceptions from tasks.
Frequently asked questions
How do I get the real exception?
Read e.InnerException. In current versions of .NET you can also call the method with BindingFlags.DoNotWrapExceptions, and get the original exception.
Why is the message always the same?
It is the fixed message of the wrapper. The message that matters is on the inner exception.
Does Task.Run wrap exceptions the same way?
No. Tasks throw the original exception when you await them, and an AggregateException when you block on them. A TargetInvocationException only comes from reflection and dynamic calls.
Is reflection slow?
Slower than a normal call, and the type information is not checked at compile time. Cache the MethodInfo, or create a delegate from it, when you call a method often.
Let your AI agent track it down
Connect Claude Code, Cursor, VS Code or Visual Studio to the elmah.io MCP server and ask your agent to look into TargetInvocationException for you. For example:
The agent reads the stack trace and request details from elmah.io, finds the code in your repository and proposes a fix. In Claude Code, add the server with one command:
claude mcp add --transport http --client-id claudecode elmahio https://mcp.elmah.io/mcp
The MCP server is included on every plan and is currently in beta. Set up the MCP server.
Further reading
YouTube videos
Answers from Stack Overflow
This has been recurring for me also and seems to be connected to extension updates but I have not yet been able to blame anything specific. What I have been able to discover is a less intrusive resolution.
In my case deleting the contents of this directory allows the IDE to recover:
%LocalAppData%\Microsoft\VisualStudio\14.0\ComponentModelCache
Edit: I just came across this one which might be handy too - Clear MEF Component Cache (Open VSIX Gallery)
By brahnp. Read the original answer on Stack Overflow.
I solved this problem by resetting the user data
devenv.exe /resetuserdata
and remove the ".vs" folder in my project.
WARNING: this will reset all your user settings. Essentially, it is like resetting to factory defaults. You will lose any custom keyboard shortcuts, extensions you've installed etc.
By Yanos. Read the original answer on Stack Overflow.
According to the MSDN, in .NET 4.0 basically you should not use ISerializable for partially trusted code, and instead you should use ISafeSerializationData
Quoting from https://learn.microsoft.com/en-us/dotnet/standard/serialization/custom-serialization
Important
In versions previous to .NET Framework 4.0, serialization of custom user data in a partially trusted assembly was accomplished using the GetObjectData. Starting with version 4.0, that method is marked with the SecurityCriticalAttribute attribute which prevents execution in partially trusted assemblies. To work around this condition, implement the ISafeSerializationData interface.
So probably not what you wanted to hear if you need it, but I don't think there's any way around it while keeping using ISerializable (other than going back to Level1 security, which you said you don't want to).
PS: the ISafeSerializationData docs state that it is just for exceptions, but it doesn't seem all that specific, you may want to give it a shot... I basically can't test it with your sample code (other than removing ISerializable works, but you knew that already)... you'll have to see if ISafeSerializationData suits you enough.
PS2: the SecurityCritical attribute doesn't work because it's ignored when the assembly is loaded in partial trust mode (on Level2 security). You can see it on your sample code, if you debug the target variable in ExecuteUntrustedCode right before invoking it, it'll have IsSecurityTransparent to true and IsSecurityCritical to false even if you mark the method with the SecurityCritical attribute)
Please update to your entity framework core nuget package to 3.1.10(or latest 5.0.0). It will solve your problem.
By Sajidur Rahman. Read the original answer on Stack Overflow.
I had EF Core 5 package installed, but not Microsoft.EntityFrameworkCore.Design and one package were implicitly referencing older version (Microsoft.EntityFrameworkCore.Design 3.0.0).
Installing explicit dependency on Microsoft.EntityFrameworkCore.Design 5.x.x resolved the issue for me.
By Alexander Goldabin. Read the original answer on Stack Overflow.
Source: Stack Overflow