{"record":{"id":"c6302fb6fc0f986b","repo":"dotnet/maui","slug":"no-test-assembly-found","errorCode":null,"errorMessage":"No test assembly found.","messagePattern":"No test assembly found\\.","errorType":"exception","errorClass":"Exception","httpStatus":null,"severity":"error","filePath":"eng/devices/devices-shared.cake","lineNumber":220,"sourceCode":"    System.Reflection.Assembly loadedAssembly = null;\n\n    foreach (var filePath in dllFilePath)\n    {\n        try\n        {\n            loadedAssembly = System.Reflection.Assembly.LoadFrom(filePath.FullPath);\n            Information($\"Loaded assembly from {filePath}: {loadedAssembly.FullName}\");\n            break; // Exit the loop if the assembly is loaded successfully\n        }\n        catch (Exception ex)\n        {\n            Warning($\"Failed to load assembly from {filePath}: {ex.Message}\");\n        }\n    }\n\n    if (loadedAssembly == null)\n    {\n        throw new Exception(\"No test assembly found.\");\n    }\n\tvar testCategoryType = loadedAssembly.GetType(\"Microsoft.Maui.DeviceTests.TestCategory\");\n\n\tvar values = new List<string>();\n\n\tforeach (var field in testCategoryType.GetFields(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static))\n\t{\n\t\tif (field.FieldType == typeof(string))\n\t\t{\n\t\t\tvalues.Add($\"Category={(string)field.GetValue(null)}\");\n\t\t}\n\t}\n\t\n\treturn values.ToList();\n}\n\nvoid HandleTestResults(string resultsDir, bool testsFailed, bool needsNameFix, string suffix = null)\n{","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/dotnet/maui/blob/f377ff1c5ee04d334d8a925f50c83a6b7afddf03/eng/devices/devices-shared.cake#L202-L238","documentation":"Thrown by GetTestCategories when reflection-loading a DeviceTests DLL (Controls or Core) fails for every candidate path found via GetFiles. The loop at line 204 swallows each Assembly.LoadFrom failure into a Warning, so this throw fires only when zero assemblies loaded successfully — meaning the build that should have produced Microsoft.Maui.Controls.DeviceTests.dll or Microsoft.Maui.Core.DeviceTests.dll never ran, or its output landed outside the searched ../../** glob.","triggerScenarios":"Calling GetTestCategories with a Controls.DeviceTests.csproj or Core.DeviceTests.csproj path before the test project has been built; building into a configuration/TFM whose bin folder the ../../** glob does not reach; a stale or deleted artifacts/bin tree after a clean; the DLL existing but being unloadable (locked, wrong architecture, corrupt) so every LoadFrom throws.","commonSituations":"Running the 'test' target without first running 'build'; switching DotnetVersion/target framework so the DLL is emitted under a new folder not matched by the glob; a clean/git-clean wiping artifacts/bin; running locally on Windows where the DLL is locked by a prior test runner process; CI caching an old artifacts dir.","solutions":["Run the build target first (dotnet cake build.cake --target=build) so the DeviceTests DLL exists under artifacts/bin before invoking GetTestCategories.","Check the Warning lines immediately before the throw — they list each attempted path and the LoadFrom exception, which identifies whether the issue is a missing file or a load failure.","Confirm projectPath ends in Controls.DeviceTests.csproj or Core.DeviceTests.csproj; other project names return early with an empty list and never reach this code, so a wrong path means the glob at line 196/200 returns nothing.","If the DLL exists but LoadFrom throws BadImageFormatException, verify the build TFM/architecture matches the host process (e.g. a net*-ios DLL cannot be LoadFrom'd on a Windows host)."],"exampleFix":"// before: glob may miss the output when the build used a non-default configuration\ndllFilePath = GetFiles($\"{directoryPath}/../../**/Microsoft.Maui.Controls.DeviceTests.dll\").ToList();\n\n// after: fall back to the known arcade bin layout and log when empty\ndllFilePath = GetFiles($\"{directoryPath}/../../**/Microsoft.Maui.Controls.DeviceTests.dll\").ToList();\nif (dllFilePath == null || dllFilePath.Count == 0)\n{\n    var arcade = MakeAbsolute(new DirectoryPath($\"../../artifacts/bin/Controls.DeviceTests/{configuration}\"));\n    dllFilePath = GetFiles($\"{arcade.FullPath}/**/Microsoft.Maui.Controls.DeviceTests.dll\").ToList();\n}\nif (dllFilePath.Count == 0)\n    throw new Exception($\"No test assembly found under {directoryPath}/../../** ; build the project first.\");","handlingStrategy":"validation","validationCode":"// Before calling GetTestCategories, confirm the DLL exists for the project\nvar expectedDll = projectPath.EndsWith(\"Controls.DeviceTests.csproj\")\n    ? \"Microsoft.Maui.Controls.DeviceTests.dll\"\n    : \"Microsoft.Maui.Core.DeviceTests.dll\";\nvar found = GetFiles($\"{Context.GetCallerInfo().SourceFilePath.GetDirectory()}/../../**/{expectedDll}\");\nif (found == null || !found.Any())\n    throw new Exception($\"Build the {expectedDll} project before requesting test categories.\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Always run the build target before the test target so DeviceTests DLLs exist.","Treat a clean of artifacts/bin as requiring a rebuild before invoking GetTestCategories.","Log the searched glob path and the count of matches before the LoadFrom loop so an empty result is obvious."],"tags":["cake","reflection","build-artifacts","device-tests","maui"],"backgroundTag":null,"analyzedSha":"f377ff1c5ee04d334d8a925f50c83a6b7afddf03","analyzedAt":"2026-08-13T14:26:18.069Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}