Unity-Technologies/UnityCsReference · error · InvalidOperationException

Replacing the root GameObject in a Prefab with a Prefab inst

Error message

Replacing the root GameObject in a Prefab with a Prefab instance is not supported since it will break all overrides for existing instances of this Prefab, including their positions and rotations.

What it means

Thrown by ThrowIfInvalidArgumentsForConvertToPrefabInstance when the plain GameObject is the root of a Prefab being edited in a Prefab Stage (PrefabStageUtility.IsGameObjectThePrefabRootInAnyPrefabStage) OR is an unparented object in a Preview Scene (EditPrefabContentsScope context). Converting the root of a Prefab/Variant to a Prefab instance would break all overrides on existing instances, so Unity blocks it.

Source

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

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

            if (IsPartOfNonAssetPrefabInstance(plainGameObject))
                throw new InvalidOperationException(string.Format("Input '{0}' is not a plain GameObject, it is already a Prefab instance. Use ReplacePrefabAssetOfPrefabInstance() instead.", plainGameObject.name));

            if (EditorUtility.IsPersistent(plainGameObject))
                throw new ArgumentException("Input is from a Prefab asset, this is not supported. Input GameObject: " + plainGameObject.name, nameof(plainGameObject));

            if (checkValidAsset)
                ThrowIfInvalidAssetForReplacePrefabInstance(prefabAssetRoot, mode);

            if (plainGameObject.transform.GetType() != prefabAssetRoot.transform.GetType())
                throw new InvalidOperationException(string.Format("Cannot convert the GameObject '{0}' with root transform of type {1} with a Prefab asset with root transform of type {2}. Transform types must match.", plainGameObject.name, plainGameObject.transform.GetType().Name, prefabAssetRoot.transform.GetType().Name));

            // Prefab Mode and EditPrefabContents scope handling
            if (PrefabStageUtility.IsGameObjectThePrefabRootInAnyPrefabStage(plainGameObject) || (EditorSceneManager.IsPreviewSceneObject(plainGameObject) && plainGameObject.transform.parent == null))
                throw new InvalidOperationException("Replacing the root GameObject in a Prefab with a Prefab instance is not supported since it will break all overrides for existing instances of this Prefab, including their positions and rotations." + plainGameObject.name);

            if (plainGameObject.hideFlags.HasFlag(HideFlags.DontSaveInEditor) || plainGameObject.transform.hideFlags.HasFlag(HideFlags.DontSaveInEditor))
                throw new ArgumentException("Input GameObject is using the HideFlags.DontSaveInEditor flag which is not supported when converting to Prefab instance: GameObject: " + plainGameObject.name, nameof(plainGameObject));

            if (mode == InteractionMode.UserAction)
            {
                // Recording undo does not handle missing scripts
                var gameObjectsWithInvalidScript = FindGameObjectsWithInvalidComponent(plainGameObject);
                if (gameObjectsWithInvalidScript.Count > 0)
                    throw new InvalidOperationException(string.Format($"Cannot convert the GameObject when it has a missing script. GameObject '{gameObjectsWithInvalidScript[0].name}' has a missing script. This is not supported by the Undo system. Use InteractionMode.AutomatedAction instead."));
            }
        }

        public static void ConvertToPrefabInstance(GameObject plainGameObject, GameObject prefabAssetRoot, ConvertToPrefabInstanceSettings settings, InteractionMode mode)
        {
            ThrowIfInvalidArgumentsForConvertToPrefabInstance(plainGameObject, prefabAssetRoot, true, mode);

            ConvertToPrefabInstance_NoInputValidation(plainGameObject, prefabAssetRoot, settings, mode);

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Convert a child object inside the Prefab, not the root, if you need to nest a Prefab instance.
  2. Close the Prefab Stage (StageUtility.GoToMainStage) and operate on a scene instance instead.
  3. Use PrefabUtility.SaveAsPrefabAsset to restructure the Prefab asset rather than converting its root.

Example fix

// before
using (var scope = new PrefabUtility.EditPrefabContentsScope(prefabPath))
{
    PrefabUtility.ConvertToPrefabInstance(scope.prefabContentsRoot, nestedPrefabAsset, settings, mode);
}

// after — convert a child, not the root
using (var scope = new PrefabUtility.EditPrefabContentsScope(prefabPath))
{
    var child = scope.prefabContentsRoot.transform.Find("Slot").gameObject;
    PrefabUtility.ConvertToPrefabInstance(child, nestedPrefabAsset, settings, mode);
}
Defensive patterns

Strategy: validation

Validate before calling

if (PrefabStageUtility.IsGameObjectThePrefabRootInAnyPrefabStage(plainGameObject)
    || (EditorSceneManager.IsPreviewSceneObject(plainGameObject) && plainGameObject.transform.parent == null))
{
    Debug.LogError("Cannot convert the root of a Prefab/Variant to a Prefab instance; convert a child instead.");
    return;
}
PrefabUtility.ConvertToPrefabInstance(plainGameObject, prefabAssetRoot, settings, mode);

Type guard

static bool IsSafeToConvert(GameObject obj)
{
    return obj != null
        && !PrefabStageUtility.IsGameObjectThePrefabRootInAnyPrefabStage(obj)
        && !(EditorSceneManager.IsPreviewSceneObject(obj) && obj.transform.parent == null);
}

Prevention

When it happens

Trigger: Opening a Prefab in Prefab Mode and running a script that calls ConvertToPrefabInstance on the root. Using EditPrefabContentsScope to load a Prefab and converting its root to a different Prefab instance.

Common situations: Editor scripts that run while a Prefab Stage is open. Batch tools that load Prefab contents and try to convert the root rather than children.

Related errors


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