Unity-Technologies/UnityCsReference · error · ArgumentException

prefabInstanceRoots has no objects

Error message

prefabInstanceRoots has no objects

What it means

Thrown by ReplacePrefabAssetOfPrefabInstances when prefabInstanceRoots.Length == 0. The batch API rejects an empty array because there is nothing to replace — this is a logic-error guard so callers don't silently no-op.

Source

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

                // 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)
        {
            ReplacePrefabAssetOfPrefabInstance(prefabInstanceRoot, prefabAssetRoot, new PrefabReplacingSettings(), mode);
        }

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Check prefabInstanceRoots.Length > 0 before calling the API.
  2. Verify your selection / filter actually yields Prefab instances before building the array.
  3. Return early from your method if the filtered list is empty.

Example fix

// before
var roots = Selection.gameObjects.Where(PrefabUtility.IsPartOfNonAssetPrefabInstance).ToArray();
PrefabUtility.ReplacePrefabAssetOfPrefabInstances(roots, prefabAsset, mode);

// after
var roots = Selection.gameObjects.Where(PrefabUtility.IsPartOfNonAssetPrefabInstance).ToArray();
if (roots.Length > 0)
    PrefabUtility.ReplacePrefabAssetOfPrefabInstances(roots, prefabAsset, mode);
Defensive patterns

Strategy: validation

Validate before calling

if (prefabInstanceRoots == null || prefabInstanceRoots.Length == 0)
    return;
PrefabUtility.ReplacePrefabAssetOfPrefabInstances(prefabInstanceRoots, prefabAssetRoot, mode);

Type guard

static bool HasAnyElements<T>(T[] array) => array != null && array.Length > 0;

Prevention

When it happens

Trigger: Passing an empty GameObject[] to ReplacePrefabAssetOfPrefabInstances — e.g. after filtering a selection down to zero Prefab instances.

Common situations: Bulk-replace script that filters Selection.gameObjects for Prefab instances but the selection contained none. A serialized list that deserialized empty. A Where/Find filter whose predicate matched nothing.

Related errors


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