{"record":{"id":"0127223a4c9d7c1e","repo":"dotnet/wpf","slug":"error-multiple-main-methods-in-classes-0-and-1","errorCode":null,"errorMessage":"Error: Multiple Main methods - in classes '{0}' and '{1}'","messagePattern":"Error: Multiple Main methods - in classes '(.+?)' and '(.+?)'","errorType":"exception","errorClass":"CspProjectException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/WpfGfx/tools/csp/Project.cs","lineNumber":279,"sourceCode":"        //  Private Methods\n        //\n        //------------------------------------------------------\n\n        #region Private Methods\n        /// <summary>\n        /// Find the class containing the Main function.\n        /// </summary>\n        private string FindMainClass()\n        {\n            string sRet = \"\";\n\n            foreach (Type t in _assembly.GetTypes())\n            {\n                if (IsMainPresent(t))\n                {\n                    if (sRet != \"\")\n                    {\n                        throw new CspProjectException(\n                            \"Error: Multiple Main methods - in classes '\" + sRet + \"' and '\" + t.FullName + \"'\");\n                    }\n\n                    sRet = t.FullName;\n                }\n\n            }\n\n            if (sRet == \"\")\n            {\n                throw new CspProjectException(\n                    \"Error: No Main method found\");\n            }\n\n            return sRet;\n        }\n\n","sourceCodeStart":261,"sourceCodeEnd":297,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/WpfGfx/tools/csp/Project.cs#L261-L297","documentation":"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.","triggerScenarios":"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().","commonSituations":"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.","solutions":["Remove or rename the extra Main method(s) so exactly one class in the assembly declares public static Main.","Make the unwanted Main non-static or non-public (e.g. private or instance), since only public static Main is detected.","If multiple entry points are genuinely needed, split the code into separate assemblies.","As a last resort, rename the alternate entry (e.g. MainBackup) and add a forwarding Main in the intended startup class."],"exampleFix":"// before\nclass App { static void Main(string[] args) { ... } }\nclass Tools { static void Main(string[] args) { ... } }\n\n// after\nclass App { static void Main(string[] args) { ... } }\nclass Tools { static void RunTools(string[] args) { ... } }","handlingStrategy":"validation","validationCode":"// Count public static Main methods in the assembly before calling ExecuteMain\nint mains = assembly.GetTypes()\n    .Count(t => t.GetMethod(\"Main\", BindingFlags.Public | BindingFlags.Static) != null);\nif (mains > 1)\n    throw new InvalidOperationException($\"Assembly has {mains} entry-point classes; expected exactly 1.\");","typeGuard":null,"tryCatchPattern":"try { project.ExecuteMain(); }\ncatch (CspProjectException ex) when (ex.Message.StartsWith(\"Error: Multiple Main methods\")) {\n    Console.Error.WriteLine($\"Fix the assembly: {ex.Message}\");\n}","preventionTips":["Keep exactly one public static Main per assembly; make helpers non-static or non-public.","Before running the tool, reflect over the assembly and assert a single entry point.","Remove leftover Main methods from test/helper classes compiled into the same assembly."],"tags":["reflection","entry-point","assembly","ambiguous"],"backgroundTag":"conflicting-config-options","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}