System.ArgumentException

An ArgumentException is thrown when a method receives an argument that it cannot accept. The argument is not null, otherwise you would get an ArgumentNullException, but its value or its state is wrong for what the method does. The ParamName property holds the name of the parameter.

It is the base class of ArgumentNullException and ArgumentOutOfRangeException, and the exception to throw from your own methods when an argument is invalid for a reason that has no more specific type.

Minimum version: >= 1.1 >= Core 1.0

Statistics

3
elmah.io logo 7

Common causes

The message names the problem, and often the parameter. These are the usual ways to hit it.

Adding a duplicate key to a dictionary

Dictionary.Add throws when the key already exists. The message includes the key: An item with the same key has already been added. Key: A-100.

var prices = new Dictionary<string, decimal>();
prices.Add("A-100", 10m);
prices.Add("A-100", 12m);   // ArgumentException

Use TryAdd to skip duplicates, or the indexer to overwrite the value:

var prices = new Dictionary<string, decimal>();
prices.Add("A-100", 10m);

if (!prices.TryAdd("A-100", 12m))
{
    prices["A-100"] = 12m;
}

Enum.Parse throws when the text does not match any member of the enum.

var day = Enum.Parse<DayOfWeek>("Funday");   // ArgumentException: Requested value 'Funday' was not found.

Use TryParse when the text comes from a user or another system:

if (Enum.TryParse<DayOfWeek>("Funday", out var day))
{
    Console.WriteLine(day);
}
else
{
    Console.WriteLine("Not a valid day.");
}

File and path methods reject an empty string. A setting that is present but empty gets past a null check and fails here.

var path = "";
var content = File.ReadAllText(path);   // ArgumentException: The value cannot be an empty string. (Parameter 'path')

Check for empty values as well as null:

var path = "";
if (!string.IsNullOrWhiteSpace(path))
{
    var content = File.ReadAllText(path);
}

If you throw an ArgumentException from your own method, pass the parameter name as the second argument. When the problem is a range, ArgumentOutOfRangeException says it better.

public class Account
{
    public void SetAge(int age)
    {
        if (age <= 0)
        {
            throw new ArgumentException("Age must be positive.", nameof(age));
        }
    }
}

Throw the more specific exception, and let the helper build the message:

public class Account
{
    public void SetAge(int age)
    {
        ArgumentOutOfRangeException.ThrowIfNegativeOrZero(age);
    }
}

How to fix it and prevent it

Prefer the TryXxx methods

Methods like TryAdd, TryParse and TryGetValue report failure with a return value. Use them whenever the input is not under your control.

var prices = new Dictionary<string, decimal>();

if (prices.TryGetValue("A-100", out var price))
{
    Console.WriteLine(price);
}

Check arguments from users, files and other systems as soon as they enter your application, and return a clear error. Code further in can then assume the values are valid.

Use ArgumentNullException for null and ArgumentOutOfRangeException for values outside a range. Throw a plain ArgumentException only when neither fits, and always include the parameter name.

public void Rename(string name)
{
    ArgumentNullException.ThrowIfNull(name);

    if (name.Contains('/'))
    {
        throw new ArgumentException("The name cannot contain a slash.", nameof(name));
    }
}

How to find the bad argument

Read the message first, because it usually names the problem. The stack trace then shows which call received the argument:

System.ArgumentException: An item with the same key has already been added. Key: A-100
   at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
   at System.Collections.Generic.Dictionary`2.Add(TKey key, TValue value)
   at Shop.Services.PriceList.Add(String sku, Decimal price) in C:\src\Shop\Services\PriceList.cs:line 14
   at Program.<Main>$(String[] args) in C:\src\Shop\Program.cs:line 5

Here the second call to PriceList.Add on line 14 passed a key that was already in the dictionary. The calling line in Program.cs shows which call came second. When the message does not name the parameter, check ParamName in the debugger.

Should you catch it?

Usually not around your own calls. An invalid argument is a bug in the caller, and it is better to fix the call or check the value first, with a TryXxx method or a condition.

It does make sense to catch it where you convert failures from outside into an error response, for example when user input fails validation. Log the exception and return a message the user can act on.

Find ArgumentException 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 trial
Free 21-day trial No credit card required

Related exceptions

  • ArgumentNullException is a derived class, thrown when an argument is null.
  • FormatException is thrown when text is not in the format a method expects, for example when parsing numbers.
  • ArgumentOutOfRangeException is a derived class, thrown when an argument is outside the allowed range, for example a list index.

Frequently asked questions

What is the difference between ArgumentException and ArgumentNullException?

ArgumentNullException is derived from ArgumentException and means the argument was null. A plain ArgumentException means the argument was not null but was not valid either.

The message often includes the parameter name, and the ParamName property always holds it when the thrower set it. The first line of the stack trace in your own code shows the call.

Yes, when an argument is invalid and no derived exception fits. Pass a message that explains what is wrong, and the parameter name with nameof.

Because keys must be unique and the key was already there. Use TryAdd to skip existing keys, or the indexer to replace the value.

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 ArgumentException for you. For example:

AI chat
Find the most frequent ArgumentException in my production log and show me the line that throws it.

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

What's happening is that you're bitten by this problem. Basically, what happened is that you didn't register your controllers explicitly in your container. Unity tries to resolve unregistered concrete types for you, but because it can't resolve it (caused by an error in your configuration), it return null. It is forced to return null, because Web API forces it to do so due to the IDependencyResolver contract. Since Unity returns null, Web API will try to create the controller itself, but since it doesn't have a default constructor it will throw the "Make sure that the controller has a parameterless public constructor" exception. This exception message is misleading and doesn't explain the real cause.

You would have seen a much clearer exception message if you registered your controllers explicitly, and that's why you should always register all root types explicitly.

But of course, the configuration error comes from you adding the second constructor to your DbContext. Unity always tries to pick the constructor with the most arguments, but it has no idea how to resolve this particular constructor.

So the real cause is that you are trying to use Unity's auto-wiring capabilities to create the DbContext. DbContext is a special type that shouldn't be auto-wired. It is a framework type and you should therefore fallback to registering it using a factory delegate:

container.Register<DashboardDbContext>(
    new InjectionFactory(c => new DashboardDbContext())); 

By Steven. Read the original answer on Stack Overflow.

Just a guess what does the variable json contain after

var json = Sys.Serialization.JavaScriptSerializer.serialize(obj);?

If it is a valid json object like {"foo":"foovalue", "bar":"barvalue"} then jQuery might not send it as json data but instead serialize it to foor=foovalue&bar=barvalue thus you get the error "Invalid JSON primitive: foo"

Try instead setting the data as string

$.ajax({
    ...
    data: '{"foo":"foovalue", "bar":"barvalue"}', //note the additional quotation marks
    ...
})

This way jQuery should leave the data alone and send the string as is to the server which should allow ASP.NET to parse the json server side.

By jitter. 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.

Complete worked example for WPF + MVVM.

Tested on MSVC 2017.

In the view:

<TextBlock Text="Some text to be colored by an enum">
    <TextBlock.Style>
        <Style TargetType="{x:Type TextBlock}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding StatusIcon}" Value="{x:Static my:StatusIcon.Warning}">
                    <Setter Property="Foreground" Value="Yellow"/>
                </DataTrigger>
                <DataTrigger Binding="{Binding StatusIcon}" Value="{x:Static my:StatusIcon.Error}">
                    <Setter Property="Foreground" Value="Red}"/>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </TextBlock.Style>
</TextBlock>

If using ReSharper, and if the DataContext is set up properly, there will be intellisense when you hit the . after StatusIcon, i.e. it will show the properties of the enum which are Debug, Info, Warning or Error.

If using ReSharper, it will suggest the following update to the namespace in the header for the XAML file(its good like that):

xmlns:my="clr-namespace:Class.Path.MyViewModel;assembly=MyAssembly"

And the VieModel:

public enum StatusIcon
{
    Debug,
    Info,
    Warning,
    Error
}

public class MyViewModel
{
    public StatusIcon StatusIcon { get; }
}

We also use Fody for automated binding.

By Contango. Read the original answer on Stack Overflow.

I had the same problem. I googled it for two days. At last I accidentally noticed that the problem was access modifier of the constructor of the Controller. I didn’t put the public key word behind the Controller’s constructor.

public class MyController : ApiController
    {
        private readonly IMyClass _myClass;

        public MyController(IMyClass myClass)
        {
            _myClass = myClass;
        }
    }

I add this experience as another answer maybe someone else made a similar mistake.

By Bob. Read the original answer on Stack Overflow.