Unity-Technologies/UnityCsReference · error · ArgumentException
Cannot add {moduleName} after UnityLinker has run because it
Error message
Cannot add {moduleName} after UnityLinker has run because it has a non-empty managed assembly. Types found: {string.Join<Type>(", ", types)}. What it means
Thrown by PostStrippingModuleAdder when attempting to add a module after the Unity managed-code linker (UnityLinker) has already run and the module's UnityEngine.{name}Module.dll still contains types. Adding such a module post-stripping would re-introduce managed code that stripping already removed.
Source
Thrown at Editor/Mono/Modules/PostStrippingModuleAdder.cs:36
m_targetData = targetData;
}
public void AddModule(string moduleName)
{
if (IsModuleIncluded(moduleName))
return;
// Check that the module has no managed component
var coreModulePath = InternalEditorUtility.GetEngineCoreModuleAssemblyPath();
var moduleAssemblyPath = Path.Combine(Path.GetDirectoryName(coreModulePath), $"UnityEngine.{moduleName}Module.dll");
//a managed assembly is still getting generated for this module, check if the assembly contains no types
if (File.Exists(moduleAssemblyPath))
{
var assembly = CurrentAssemblies.LoadFromPath(moduleAssemblyPath);
var types = assembly.GetTypes();
if (types.Length > 0)
throw new ArgumentException($"Cannot add {moduleName} after UnityLinker has run because it has a non-empty managed assembly. Types found: {string.Join<Type>(", ", types)}.");
}
// Check that all the module's dependencies are already on the list
var moduleDependencyNames = ModuleMetadata.GetModuleDependencies(moduleName);
var moduleDependencies = new List<LinkerToEditorData.ReportData.Dependency>();
var missingDependencyNames = new List<string>();
foreach (var dependency in moduleDependencyNames)
{
if (!IsModuleIncluded(dependency))
{
missingDependencyNames.Add(dependency);
//no need to process this entry further as it is missing from the included module list
continue;
}
moduleDependencies.Add(new LinkerToEditorData.ReportData.DependencyView on GitHub (pinned to 225b0fbdb5)
Solutions
- Ensure the module is added BEFORE stripping runs (correct build phase ordering).
- Lower managedStrippingLevel or exclude the assembly from stripping so the post-stripping invariant holds, or ensure the assembly is genuinely empty.
- Re-run a full clean build so stripping and module-add operate on a consistent state.
Example fix
// before: add module after linker left types in the assembly
AddModule("MyModule"); // throws
// after: move registration to pre-stripping phase
// or exclude the assembly in link.xml
<assembly fullname="UnityEngine.MyModuleModule" preserve="all"/> Defensive patterns
Strategy: validation
Validate before calling
var path = Path.Combine(Path.GetDirectoryName(InternalEditorUtility.GetEngineCoreModuleAssemblyPath()), $"UnityEngine.{moduleName}Module.dll");
bool canAddPostStrip = !File.Exists(path) || CurrentAssemblies.LoadFromPath(path).GetTypes().Length == 0; Try / catch
try { AddModule(name); }
catch (ArgumentException ex) when (ex.Message.Contains("non-empty managed assembly"))
{ /* move add to pre-stripping phase */ } Prevention
- Register modules before the UnityLinker step.
- Keep build phase ordering consistent.
- Run clean builds after changing stripping config.
When it happens
Trigger: Calling the module-add API (after IL stripping) for a module whose assembly was not fully stripped — types remain, indicating the linker did not process it for removal.
Common situations: Custom post-stripping module registration logic runs out of order. Stripping configuration (managedStrippingLevel) changed mid-build. Module added via editor script after a partial build.
Related errors
- Cannot add module {moduleName} because it has dependencies o
- Couldn't find module for target: {device.module}
- Couldn't create device API for device: {deviceId}
- target must be valid
- path
AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13).
Data as JSON: /api/errors/fcc192a43c887fce.
Report an issue: GitHub.