{"record":{"id":"266f440806adc483","repo":"egametang/ET","slug":"hot-update-assembly-name-cann-t-be-empty","errorCode":null,"errorMessage":"hot update assembly name cann't be empty","messagePattern":"hot update assembly name cann't be empty","errorType":"validation","errorClass":"BuildFailedException","httpStatus":null,"severity":"error","filePath":"Packages/cn.etetet.hybridclr/Scripts/Editor/Share/BuildProcessors/FilterHotFixAssemblies.cs","lineNumber":36,"sourceCode":"    {\n        public int callbackOrder => 0;\n\n        public string[] OnFilterAssemblies(BuildOptions buildOptions, string[] assemblies)\n        {\n            if (!SettingsUtil.Enable)\n            {\n                Debug.Log($\"[FilterHotFixAssemblies] disabled\");\n                return assemblies;\n            }\n            List<string> allHotUpdateDllNames = SettingsUtil.HotUpdateAssemblyNamesExcludePreserved;\n\n            // 检查是否重复填写\n            var hotUpdateDllSet = new HashSet<string>();\n            foreach(var hotUpdateDll in allHotUpdateDllNames)\n            {\n                if (string.IsNullOrWhiteSpace(hotUpdateDll))\n                {\n                    throw new BuildFailedException($\"hot update assembly name cann't be empty\");\n                }\n                if (!hotUpdateDllSet.Add(hotUpdateDll))\n                {\n                    throw new BuildFailedException($\"hot update assembly:{hotUpdateDll} is duplicated\");\n                }\n            }\n\n            var assResolver = MetaUtil.CreateHotUpdateAssemblyResolver(EditorUserBuildSettings.activeBuildTarget, allHotUpdateDllNames);\n            // 检查是否填写了正确的dll名称\n            foreach (var hotUpdateDllName in allHotUpdateDllNames)\n            {\n                if (assemblies.Select(Path.GetFileNameWithoutExtension).All(ass => ass != hotUpdateDllName) \n                    && string.IsNullOrEmpty(assResolver.ResolveAssembly(hotUpdateDllName, false)))\n                {\n                    throw new BuildFailedException($\"hot update assembly:{hotUpdateDllName} doesn't exist\");\n                }\n            }\n","sourceCodeStart":18,"sourceCodeEnd":54,"githubUrl":"https://github.com/egametang/ET/blob/5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f/Packages/cn.etetet.hybridclr/Scripts/Editor/Share/BuildProcessors/FilterHotFixAssemblies.cs#L18-L54","documentation":"Thrown by FilterHotFixAssemblies.OnFilterBuildAssemblies when iterating over the configured hot-update assembly names and encountering one that is null, empty, or whitespace. This runs during the build's assembly-filtering phase to strip hot-update DLLs from the main build. An empty entry in the list is treated as a configuration error rather than silently skipped.","triggerScenarios":"OnFilterBuildAssemblies iterates SettingsUtil.HotUpdateAssemblyNamesExcludePreserved (which combines hotUpdateAssemblies and hotUpdateAssemblyDefinitions from HybridCLRSettings). If any entry is null or whitespace, the BuildFailedException is thrown during build preprocessing.","commonSituations":"A stray empty string or null in the HybridCLRSettings hotUpdateAssemblies array (e.g. left by the Unity inspector when adding then clearing an element); a serialized settings asset with a trailing empty entry; programmatic settings modification that inserted null; copy-paste errors leaving blank lines in the list.","solutions":["Open HybridCLRSettings (Project Settings > HybridCLR or the settings asset) and remove any empty or blank entries from the hot update assemblies list.","If managing settings programmatically, filter out null/empty strings before assigning the array.","Inspect the serialized HybridCLRSettings asset in a text editor to find stray empty elements.","Re-enter the hot update assembly names cleanly, ensuring each is a valid assembly name without whitespace."],"exampleFix":"// before — settings contains: [\"HotUpdate\", \"\", \"GameLogic\"]\n// FilterHotFixAssemblies throws on the empty entry\n\n// fix — clean the list in HybridCLRSettings:\n// hotUpdateAssemblies: [\"HotUpdate\", \"GameLogic\"]  (remove the empty string)\n\n// programmatic guard before build:\nvar names = SettingsUtil.HybridCLRSettings.hotUpdateAssemblies\n    .Where(n => !string.IsNullOrWhiteSpace(n))\n    .ToArray();\nSettingsUtil.HybridCLRSettings.hotUpdateAssemblies = names;","handlingStrategy":"validation","validationCode":"var names = SettingsUtil.HybridCLRSettings.hotUpdateAssemblies;\nif (names != null)\n{\n    foreach (var name in names)\n    {\n        if (string.IsNullOrWhiteSpace(name))\n        {\n            Debug.LogError(\"An empty or null entry exists in HybridCLRSettings.hotUpdateAssemblies. Remove it before building.\");\n        }\n    }\n}","typeGuard":"static bool HasNoEmptyEntries(string[] names)\n{\n    return names == null || names.All(n => !string.IsNullOrWhiteSpace(n));\n}","tryCatchPattern":"try\n{\n    BuildPipeline.BuildPlayer(scenes, outputPath, buildTarget, buildOptions);\n}\ncatch (BuildFailedException ex) when (ex.Message.Contains(\"cann't be empty\"))\n{\n    Debug.LogError(\"A hot-update assembly name is empty. Open HybridCLRSettings and remove blank entries.\");\n}","preventionTips":["When editing the hotUpdateAssemblies list in the inspector, delete empty array elements rather than clearing them.","Inspect the serialized HybridCLRSettings asset file for stray empty strings.","Programmatically filter out null/empty entries before assigning the settings array.","Add a pre-build validation step that checks for empty or invalid assembly names."],"tags":["hybridclr","build-processor","hot-update","configuration","settings","validation"],"backgroundTag":null,"analyzedSha":"5cab01f7a8bee5f49f4781eebe9e2b1c6d7ebe0f","analyzedAt":"2026-08-13T21:10:40.377Z","schemaVersion":2},"datasetVersion":"2026-08-14T00:17:13.853Z"}