dotnet/wpf · error · CspProjectException

Error: Multiple Main methods in class

Error message

Error: Multiple Main methods in class '{0}'

What it means

IsMainPresent (Project.cs:302) calls Type.GetMethod("Main", Public|Static), which throws AmbiguousMatchException when a single class declares more than one public static Main overload. The tool treats this as fatal and rethrows it as CspProjectException naming the offending class, because it cannot disambiguate the entry point.

Solutions

  1. Keep exactly one public static Main per class; delete or rename the duplicate overload (e.g. to MainInternal).
  2. Reduce visibility of the unwanted overload (non-public or non-static) so it no longer matches Public|Static binding flags.
  3. Use #if directives to compile only one Main overload per build configuration.

Example fix

// before
public static void Main(string[] args) { Run(args); }
public static int Main() { Run(new string[0]); return 0; }

// after
public static void Main(string[] args) { Run(args); }
private static int MainNoArgs() { Run(new string[0]); return 0; }
Defensive patterns

Strategy: validation

Validate before calling

// Detect classes with ambiguous Main overloads before execution
var bad = assembly.GetTypes().Where(t =>
    t.GetMethods(BindingFlags.Public | BindingFlags.Static)
     .Count(m => m.Name == "Main") > 1).ToList();
if (bad.Count > 0)
    throw new InvalidOperationException("Ambiguous Main overloads in: " + string.Join(",", bad.Select(t => t.FullName)));

Try / catch

try { project.ExecuteMain(); }
catch (CspProjectException ex) when (ex.Message.StartsWith("Error: Multiple Main methods in class")) {
    Console.Error.WriteLine($"Remove duplicate Main overloads: {ex.Message}");
}

Prevention

When it happens

Trigger: The assembly contains a class with two or more public static methods named 'Main' (e.g. static void Main(string[]) and static int Main()) so Type.GetMethod cannot return a single MethodInfo.

Common situations: Hand-written overloads of Main for testing, copy-pasted Main signatures in the startup class, conditional-compilation or refactoring leftovers that left two entry-point-shaped methods in one class.

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/ba7aa9984edff36a. Report an issue: GitHub.

Appendix: source

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


        /// <summary>
        /// Tests whether the type has a Main method.
        /// Throws an exception if more than one is present.
        /// </summary>
        private bool IsMainPresent(Type t)
        {
            MethodInfo method = null;
            try
            {
                method = t.GetMethod(
                    "Main",
                    BindingFlags.Public | BindingFlags.Static
                    );
            }
            catch (System.Reflection.AmbiguousMatchException)
            {
                throw new CspProjectException(
                    "Error: Multiple Main methods in class '" + t.FullName + "'");
            }

            return method != null;
        }

        /// <summary>
        /// Report an exception to the console.
        /// </summary>
        private static void ReportException(Exception e)
        {
            throw new ApplicationException(e.Message);
        }


        #endregion Private Methods

View on GitHub (pinned to 81131a70a4)