Unity-Technologies/UnityCsReference · error · ArgumentException

Input instance is not an outermost Prefab instance root. Inp

Error message

Input instance is not an outermost Prefab instance root. Input instance: 

What it means

Thrown by ThrowIfInvalidArgumentsForReplacePrefabInstance when IsOutermostPrefabInstanceRoot(prefabInstanceRoot) returns false. The API requires the top-level (outermost) Prefab instance root in the hierarchy — a nested child that is itself a Prefab instance is rejected because replacing only the inner instance would corrupt the parent instance structure.

Source

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

                throw new InvalidOperationException(string.Format($"Cannot replace the Prefab instance with the Prefab Asset '{AssetDatabase.GetAssetPath(prefabAsset)}' because it has a missing script. GameObject '{gameObjectsWithInvalidScript[0].name}' in the Prefab Asset has a missing script."));
        }

        internal static void ThrowIfInvalidArgumentsForReplacePrefabInstance(GameObject prefabInstanceRoot, GameObject prefabAssetRoot, bool checkValidAsset, InteractionMode mode)
        {
            if (prefabInstanceRoot == null)
                throw new ArgumentNullException(nameof(prefabInstanceRoot));

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

            if (checkValidAsset)
                ThrowIfInvalidAssetForReplacePrefabInstance(prefabAssetRoot, mode);

            if (!IsPartOfNonAssetPrefabInstance(prefabInstanceRoot))
                throw new InvalidOperationException(string.Format("Input '{0}' is not a Prefab instance, for plain GameObjects use ConvertToPrefabInstance() instead", prefabInstanceRoot.name));

            if (!IsOutermostPrefabInstanceRoot(prefabInstanceRoot))
                throw new ArgumentException("Input instance is not an outermost Prefab instance root. Input instance: " + prefabInstanceRoot.name, nameof(prefabInstanceRoot));
            if (EditorUtility.IsPersistent(prefabInstanceRoot))
                throw new ArgumentException("Input instance root is from a Prefab asset, this is not supported. Input instance: " + prefabInstanceRoot.name, nameof(prefabInstanceRoot));

            if (PrefabStageUtility.IsGameObjectThePrefabRootInAnyPrefabStage(prefabInstanceRoot))
                throw new InvalidOperationException("Replacing the root Prefab instance in a Variant is not supported since it will break all overrides for existing instances of this Variant, including their positions and rotations." + prefabInstanceRoot.name);
            if (IsAnyPrefabInstanceRoot(prefabInstanceRoot) && EditorSceneManager.IsPreviewSceneObject(prefabInstanceRoot) && prefabInstanceRoot.transform.parent == null) // EditPrefabContentsScope handling
                throw new InvalidOperationException("Replacing the Variant parent is not supported since it will break all overrides for existing instances of this Variant, including their positions and rotations." + prefabInstanceRoot.name);
            if (prefabInstanceRoot.transform.GetType() != prefabAssetRoot.transform.GetType())
                throw new InvalidOperationException(string.Format("Cannot replace the Prefab instance '{0}' with root transform of type {1} with a Prefab asset with root transform of type {2}. Transform types must match.", prefabInstanceRoot.name, prefabInstanceRoot.transform.GetType().Name, prefabAssetRoot.transform.GetType().Name));

            if (prefabInstanceRoot.hideFlags.HasFlag(HideFlags.DontSaveInEditor) || prefabInstanceRoot.transform.hideFlags.HasFlag(HideFlags.DontSaveInEditor))
                throw new ArgumentException("Input instance root is using the HideFlags.DontSaveInEditor flag which is not supported when replacing: Input instance: " + prefabInstanceRoot.name, nameof(prefabInstanceRoot));

            if (mode == InteractionMode.UserAction)
            {
                // Recording undo does not handle missing scripts
                var gameObjectsWithInvalidScript = FindGameObjectsWithInvalidComponent(prefabInstanceRoot);
                if (gameObjectsWithInvalidScript.Count > 0)

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Traverse up to the outermost parent Prefab instance using PrefabUtility.GetOutermostPrefabInstanceRoot(obj) and pass that instead.
  2. Filter your candidate list with PrefabUtility.IsOutermostPrefabInstanceRoot(obj) before calling the API.
  3. If you genuinely need to replace a nested instance, unpack the outer instance first, replace, then re-pack.

Example fix

// before
PrefabUtility.ReplacePrefabAssetOfPrefabInstance(nestedInstance, prefabAsset, mode);

// after
var outer = PrefabUtility.GetOutermostPrefabInstanceRoot(nestedInstance);
PrefabUtility.ReplacePrefabAssetOfPrefabInstance(outer, prefabAsset, mode);
Defensive patterns

Strategy: validation

Validate before calling

// Resolve to the outermost root before calling
var outer = PrefabUtility.GetOutermostPrefabInstanceRoot(prefabInstanceRoot);
if (outer != null && PrefabUtility.IsOutermostPrefabInstanceRoot(outer))
    PrefabUtility.ReplacePrefabAssetOfPrefabInstance(outer, prefabAssetRoot, mode);

Type guard

static bool IsOutermostRoot(GameObject obj)
{
    return obj != null && PrefabUtility.IsOutermostPrefabInstanceRoot(obj);
}

Prevention

When it happens

Trigger: Passing a nested Prefab instance (a child object that is its own Prefab instance root but sits inside another Prefab instance) to ReplacePrefabAssetOfPrefabInstance. E.g. a weapon Prefab nested inside a character Prefab instance.

Common situations: Iterating over all Prefab instance roots found via GetRootGameObject on children and passing inner instances to the replace API. Selecting a deeply nested Prefab in the Hierarchy and running a bulk-replace script.

Related errors


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