Unity-Technologies/UnityCsReference · error · ArgumentNullException

prefabInstanceRoots

Error message

prefabInstanceRoots

What it means

Thrown by ReplacePrefabAssetOfPrefabInstances when the prefabInstanceRoots array is null. This is a standard ArgumentNullException guard on the first parameter of the batch replace API. The nameof(prefabInstanceRoots) string is used as the argument name in the exception.

Source

Thrown at Editor/Mono/Prefabs/PrefabUtility.cs:2283

            if (mode == InteractionMode.UserAction)
            {
                // Recording undo does not handle missing scripts
                var gameObjectsWithInvalidScript = FindGameObjectsWithInvalidComponent(prefabInstanceRoot);
                if (gameObjectsWithInvalidScript.Count > 0)
                    throw new InvalidOperationException(string.Format($"Cannot replace the Prefab instance when it has a missing script. GameObject '{gameObjectsWithInvalidScript[0].name}' has a missing script. Use InteractionMode.AutomatedAction to force the replace."));
            }
        }

        public static void ReplacePrefabAssetOfPrefabInstances(GameObject[] prefabInstanceRoots, GameObject prefabAssetRoot, InteractionMode mode)
        {
            ReplacePrefabAssetOfPrefabInstances(prefabInstanceRoots, prefabAssetRoot, new PrefabReplacingSettings(), mode);
        }

        public static void ReplacePrefabAssetOfPrefabInstances(GameObject[] prefabInstanceRoots, GameObject prefabAssetRoot, PrefabReplacingSettings settings, InteractionMode mode)
        {
            if (prefabInstanceRoots == null)
                throw new ArgumentNullException(nameof(prefabInstanceRoots));

            if (prefabInstanceRoots.Length == 0)
                throw new ArgumentException(nameof(prefabInstanceRoots) + " has no objects");

            if (settings == null)
                throw new ArgumentNullException(nameof(settings));

            ThrowIfInvalidAssetForReplacePrefabInstance(prefabAssetRoot, mode);
            foreach (var go in prefabInstanceRoots)
                ThrowIfInvalidArgumentsForReplacePrefabInstance(go, prefabAssetRoot, false, mode);

            foreach (var go in prefabInstanceRoots)
                ReplacePrefabAssetOfPrefabInstance_NoInputValidation(go, prefabAssetRoot, settings, mode);

            EditorUtility.ForceRebuildInspectors();
        }

        public static void ReplacePrefabAssetOfPrefabInstance(GameObject prefabInstanceRoot, GameObject prefabAssetRoot, InteractionMode mode)

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Null-check the array before calling the API.
  2. Initialize the array to an empty array instead of leaving it null.
  3. Use Selection.gameObjects?.Where(...) ?? Array.Empty<GameObject>() to guarantee non-null.

Example fix

// before
PrefabUtility.ReplacePrefabAssetOfPrefabInstances(myArray, prefabAsset, mode);
// myArray could be null

// after
if (myArray != null && myArray.Length > 0)
    PrefabUtility.ReplacePrefabAssetOfPrefabInstances(myArray, prefabAsset, mode);
Defensive patterns

Strategy: validation

Validate before calling

if (prefabInstanceRoots == null)
{
    Debug.LogError("prefabInstanceRoots is null.");
    return;
}
PrefabUtility.ReplacePrefabAssetOfPrefabInstances(prefabInstanceRoots, prefabAssetRoot, mode);

Prevention

When it happens

Trigger: Calling ReplacePrefabAssetOfPrefabInstances(null, prefabAsset, mode) — e.g. a variable that was never assigned, or a LINQ result that returned null on an empty source.

Common situations: Selection.gameObjects passed without null-checking when nothing is selected. Deserialized data that failed to populate the array. Code path where the array is conditionally populated but the condition was false.

Related errors


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