dotnet/wpf · error · CspProjectException

Error: Multiple Main methods - in classes

Error message

Error: Multiple Main methods - in classes '{0}' and '{1}'

What it means

The csp tool locates the entry point of the input assembly by reflecting over all types and finding which class declares a public static Main (FindMainClass in Project.cs:269). It requires exactly one such class. When a second type with a Main method is encountered after one was already found, it throws CspProjectException naming both classes, because it cannot decide which entry point to invoke.

Solutions

  1. Remove or rename the extra Main method(s) so exactly one class in the assembly declares public static Main.
  2. Make the unwanted Main non-static or non-public (e.g. private or instance), since only public static Main is detected.
  3. If multiple entry points are genuinely needed, split the code into separate assemblies.
  4. As a last resort, rename the alternate entry (e.g. MainBackup) and add a forwarding Main in the intended startup class.

Example fix

// before
class App { static void Main(string[] args) { ... } }
class Tools { static void Main(string[] args) { ... } }

// after
class App { static void Main(string[] args) { ... } }
class Tools { static void RunTools(string[] args) { ... } }
Defensive patterns

Strategy: validation

Validate before calling

// Count public static Main methods in the assembly before calling ExecuteMain
int mains = assembly.GetTypes()
    .Count(t => t.GetMethod("Main", BindingFlags.Public | BindingFlags.Static) != null);
if (mains > 1)
    throw new InvalidOperationException($"Assembly has {mains} entry-point classes; expected exactly 1.");

Try / catch

try { project.ExecuteMain(); }
catch (CspProjectException ex) when (ex.Message.StartsWith("Error: Multiple Main methods")) {
    Console.Error.WriteLine($"Fix the assembly: {ex.Message}");
}

Prevention

When it happens

Trigger: Calling ExecuteMain on a compiled assembly whose reflected types contain more than one class with a public static void Main(string[]) method. The exception fires on the second matching type during the foreach over _assembly.GetTypes().

Common situations: Projects that merged several application sources into one library/assembly, leftover Main methods in test or helper classes compiled into the same assembly, and code migrated where the old entry point was kept after a new one was added.

Understand the failure class

Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.

Related errors


AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14). Data as JSON: /api/errors/0127223a4c9d7c1e. Report an issue: GitHub.

Appendix: source

Thrown at src/Microsoft.DotNet.Wpf/src/WpfGfx/tools/csp/Project.cs:279

        //  Private Methods
        //
        //------------------------------------------------------

        #region Private Methods
        /// <summary>
        /// Find the class containing the Main function.
        /// </summary>
        private string FindMainClass()
        {
            string sRet = "";

            foreach (Type t in _assembly.GetTypes())
            {
                if (IsMainPresent(t))
                {
                    if (sRet != "")
                    {
                        throw new CspProjectException(
                            "Error: Multiple Main methods - in classes '" + sRet + "' and '" + t.FullName + "'");
                    }

                    sRet = t.FullName;
                }

            }

            if (sRet == "")
            {
                throw new CspProjectException(
                    "Error: No Main method found");
            }

            return sRet;
        }

View on GitHub (pinned to 81131a70a4)