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.Dependency

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Ensure the module is added BEFORE stripping runs (correct build phase ordering).
  2. Lower managedStrippingLevel or exclude the assembly from stripping so the post-stripping invariant holds, or ensure the assembly is genuinely empty.
  3. 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

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


AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13). Data as JSON: /api/errors/fcc192a43c887fce. Report an issue: GitHub.