egametang/ET · error · BuildFailedException
hot update assembly:{hotUpdateDll} is duplicated
Error message
hot update assembly:{hotUpdateDll} is duplicated What it means
Thrown by FilterHotFixAssemblies.OnFilterBuildAssemblies when a hot-update assembly name appears more than once in the combined list. The code uses a HashSet<string> to detect duplicates; HashSet.Add returns false if the element already exists. A duplicate is a configuration error because it would cause ambiguous assembly filtering and potential double-processing.
Source
Thrown at Packages/cn.etetet.hybridclr/Scripts/Editor/Share/BuildProcessors/FilterHotFixAssemblies.cs:40
{
if (!SettingsUtil.Enable)
{
Debug.Log($"[FilterHotFixAssemblies] disabled");
return assemblies;
}
List<string> allHotUpdateDllNames = SettingsUtil.HotUpdateAssemblyNamesExcludePreserved;
// 检查是否重复填写
var hotUpdateDllSet = new HashSet<string>();
foreach(var hotUpdateDll in allHotUpdateDllNames)
{
if (string.IsNullOrWhiteSpace(hotUpdateDll))
{
throw new BuildFailedException($"hot update assembly name cann't be empty");
}
if (!hotUpdateDllSet.Add(hotUpdateDll))
{
throw new BuildFailedException($"hot update assembly:{hotUpdateDll} is duplicated");
}
}
var assResolver = MetaUtil.CreateHotUpdateAssemblyResolver(EditorUserBuildSettings.activeBuildTarget, allHotUpdateDllNames);
// 检查是否填写了正确的dll名称
foreach (var hotUpdateDllName in allHotUpdateDllNames)
{
if (assemblies.Select(Path.GetFileNameWithoutExtension).All(ass => ass != hotUpdateDllName)
&& string.IsNullOrEmpty(assResolver.ResolveAssembly(hotUpdateDllName, false)))
{
throw new BuildFailedException($"hot update assembly:{hotUpdateDllName} doesn't exist");
}
}
// 将热更dll从打包列表中移除
return assemblies.Where(ass =>
{
string assName = Path.GetFileNameWithoutExtension(ass);View on GitHub (pinned to 5cab01f7a8)
Solutions
- Open HybridCLRSettings and check for the duplicated assembly name across both hotUpdateAssemblies and hotUpdateAssemblyDefinitions fields.
- Remove the duplicate so each hot-update assembly appears exactly once.
- If using AssemblyDefinitionAsset references, cross-reference them against the string list to avoid overlaps.
- Audit the settings asset file directly in a text editor to catch duplicates the inspector might obscure.
Example fix
// before — settings:
// hotUpdateAssemblies: ["GameLogic", "HotUpdate"]
// hotUpdateAssemblyDefinitions: [GameLogic.asmdef] // "GameLogic" duplicated
// FilterHotFixAssemblies throws: "hot update assembly:GameLogic is duplicated"
// fix — keep GameLogic in only one list:
// hotUpdateAssemblies: ["HotUpdate"]
// hotUpdateAssemblyDefinitions: [GameLogic.asmdef]
// programmatic dedup guard before build:
var combined = new HashSet<string>(StringComparer.Ordinal);
foreach (var name in allNames.Where(n => !string.IsNullOrWhiteSpace(n)))
if (!combined.Add(name))
Debug.LogWarning($"Duplicate hot-update assembly will be removed: {name}"); Defensive patterns
Strategy: validation
Validate before calling
var names = SettingsUtil.HotUpdateAssemblyNamesExcludePreserved;
var seen = new HashSet<string>(StringComparer.Ordinal);
foreach (var name in names.Where(n => !string.IsNullOrWhiteSpace(n)))
{
if (!seen.Add(name))
{
Debug.LogError($"Duplicate hot-update assembly name detected: '{name}'. " +
"Check both hotUpdateAssemblies and hotUpdateAssemblyDefinitions for overlap.");
}
} Type guard
static bool HasNoDuplicates(string[] names)
{
var clean = names.Where(n => !string.IsNullOrWhiteSpace(n));
return clean.Count() == new HashSet<string>(clean, StringComparer.Ordinal).Count;
} Try / catch
try
{
BuildPipeline.BuildPlayer(scenes, outputPath, buildTarget, buildOptions);
}
catch (BuildFailedException ex) when (ex.Message.Contains("is duplicated"))
{
Debug.LogError("A hot-update assembly name is listed more than once. " +
"Check hotUpdateAssemblies and hotUpdateAssemblyDefinitions for duplicates.");
} Prevention
- Cross-check hotUpdateAssemblies (string list) against hotUpdateAssemblyDefinitions (asset list) to avoid overlap.
- When moving an assembly between lists, remove it from the old one.
- Run a dedup check on the combined assembly name list before building.
- Inspect the HybridCLRSettings asset directly to catch duplicates the inspector may not surface.
When it happens
Trigger: OnFilterBuildAssemblies builds hotUpdateDllSet from HotUpdateAssemblyNamesExcludePreserved. If the same assembly name is listed in both hotUpdateAssemblies and hotUpdateAssemblyDefinitions, or duplicated within either list, the HashSet.Add returns false and the exception fires.
Common situations: Listing the same assembly in both the 'hotUpdateAssemblies' (string list) and 'hotUpdateAssemblyDefinitions' (definition list) fields of HybridCLRSettings; duplicating an entry within one list (common with Unity inspector array manipulation); refactoring settings where an assembly was moved between lists but not removed from the old one.
Related errors
- hot update assembly name cann't be empty
- resolve Hot update dll:{assemblyName} failed! Please make su
- can't find xxxx.xcodeproj/project.pbxproj in {pathToBuiltPro
- hot update assembly:{hotUpdateDllName} doesn't exist
- ERR_LocationPrimaryUnavailable
AI-assisted analysis of egametang/ET@5cab01f7a8 (2026-08-13).
Data as JSON: /api/errors/3851a6c3e1769fd5.
Report an issue: GitHub.