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
- Traverse up to the outermost parent Prefab instance using PrefabUtility.GetOutermostPrefabInstanceRoot(obj) and pass that instead.
- Filter your candidate list with PrefabUtility.IsOutermostPrefabInstanceRoot(obj) before calling the API.
- 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
- Use PrefabUtility.GetOutermostPrefabInstanceRoot to normalize any instance reference before calling replace.
- When iterating GetComponentsInChildren, filter out nested instance roots or resolve them to their outermost parent.
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
- Input '{0}' is not a Prefab instance, for plain GameObjects
- Input instance root is from a Prefab asset, this is not supp
- Replacing the root Prefab instance in a Variant is not suppo
- Cannot replace the Prefab instance '{0}' with root transform
- Input instance root is using the HideFlags.DontSaveInEditor
AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13).
Data as JSON: /api/errors/7922c2ba0f630ff1.
Report an issue: GitHub.