Skip to main content

How to Resolve Error "CS1015: An object, string, or class type expected" in C#

The Compiler Error CS1015 is a syntax and type restriction error typically found in Exception Handling. The message reads: "An object, string, or class type expected".

In C#, try...catch blocks are designed to handle Exceptions. An Exception in .NET is an object that inherits from the System.Exception class. This error occurs when you attempt to define a catch block for a data type that is not a class (like a primitive int or double) or not a valid object reference type in the context of the compiler's parser. While mostly seen in older C# code or specific compiler versions (modern compilers often flag this as CS0155: The type caught or thrown must be derived from System.Exception), CS1015 specifically flags attempts to pass predefined primitive keywords into a catch block.

This guide explains the rules of exception handling and how to fix this error.

Understanding Valid Catch Types

The C# language specification requires that every object caught in a catch block must be convertible to System.Exception.

  • Valid: catch (ArgumentNullException), catch (Exception), catch (MyCustomError).
  • Invalid: catch (int), catch (string), catch (double).

Although the Common Language Runtime (CLR) technically allows throwing any object (even strings or integers) in non-C# languages (like C++/CLI), C# enforces that you handle these only as standard Exceptions.

Scenario: Catching Primitives (int, string)

This error occurs if you try to treat a catch block like a switch statement for error codes or messages.

Example of error: attempting to catch an integer error code directly.

public void ProcessData()
{
try
{
// ... code that might throw ...
}
// ⛔️ Error CS1015: An object, string, or class type expected
// You cannot catch 'int'. Exceptions are objects, not numbers.
catch (int errorCode)
{
System.Console.WriteLine($"Error Code: {errorCode}");
}
}

Solution: Catch System.Exception

You must catch a specific Exception type. If you are interacting with a library that throws specific exception types, catch those. If you need a catch-all, catch System.Exception.

Solution: change the type to Exception.

using System;

public void ProcessData()
{
try
{
// ... code ...
}
// ✅ Correct: Catches any standard .NET exception
catch (Exception ex)
{
System.Console.WriteLine($"Error: {ex.Message}");
}
}

Advanced: Non-CLS Exceptions

In very rare interoperability scenarios, you might interact with a library written in C++/CLI or IL that throws a non-Exception object (e.g., it literally throw 42;).

Historically, C# could not catch these variables directly. However, modern C# wraps these non-standard exceptions into a System.Runtime.CompilerServices.RuntimeWrappedException.

If you specifically want to handle everything, including these "weird" non-CLS exceptions:

try
{
// Call legacy C++ code
}
catch (System.Runtime.CompilerServices.RuntimeWrappedException e)
{
// The actual non-exception object is inside e.WrappedException
object originalPayload = e.WrappedException;
Console.WriteLine("Caught a non-CLS exception");
}
catch (Exception e)
{
// Standard exceptions
}

Conclusion

CS1015 is a parser error telling you that catch blocks are for Classes, not Primitives.

  1. Check the Type: Look inside catch (...).
  2. Remove Primitives: If you see int, string, float, replace them.
  3. Use Exception: Replace the invalid type with Exception or a specific derived class (like InvalidOperationException).