Unity-Technologies/UnityCsReference · error · InvalidOperationException

Replacing the Variant parent is not supported since it will

Error message

Replacing the Variant parent is not supported since it will break all overrides for existing instances of this Variant, including their positions and rotations.

What it means

Thrown by ThrowIfInvalidArgumentsForReplacePrefabInstance when IsAnyPrefabInstanceRoot(prefabInstanceRoot) && EditorSceneManager.IsPreviewSceneObject(prefabInstanceRoot) && prefabInstanceRoot.transform.parent == null — i.e. the object is an unparented Prefab instance root in a Preview Scene (the EditPrefabContentsScope pattern). Replacing a Variant's parent under these conditions would break all overrides on existing instances of that Variant.

Source

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

            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)
                    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);

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Instead of replacing the Variant parent via EditPrefabContentsScope, create a new Variant from the desired base using SaveAsPrefabAsset with the variant flag.
  2. Operate on a live scene instance of the Variant (not a preview-scene root) if you need ReplacePrefabAssetOfPrefabInstance.
  3. Guard: check EditorSceneManager.IsPreviewSceneObject(obj) and skip or take an alternate path.

Example fix

// before
using (var scope = new PrefabUtility.EditPrefabContentsScope(variantPath))
{
    PrefabUtility.ReplacePrefabAssetOfPrefabInstance(scope.prefabContentsRoot, newBaseAsset, mode);
}

// after — recreate the Variant from the new base instead
var contents = PrefabUtility.LoadPrefabContents(variantPath);
var newPath = AssetDatabase.GenerateUniqueAssetPath("Assets/NewVariant.prefab");
PrefabUtility.SaveAsPrefabAsset(contents, newPath, out bool success);
Defensive patterns

Strategy: validation

Validate before calling

if (IsAnyPrefabInstanceRoot(prefabInstanceRoot)
    && EditorSceneManager.IsPreviewSceneObject(prefabInstanceRoot)
    && prefabInstanceRoot.transform.parent == null)
{
    Debug.LogWarning("Cannot replace Variant parent in a preview scene; recreate the Variant instead.");
    return;
}
PrefabUtility.ReplacePrefabAssetOfPrefabInstance(prefabInstanceRoot, prefabAssetRoot, mode);

Type guard

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

Prevention

When it happens

Trigger: Using PrefabUtility.EditPrefabContentsScope (or the older LoadPrefabContents) to open a Variant asset, then calling ReplacePrefabAssetOfPrefabInstance on the root of the loaded contents. Attempting to swap a Variant's parent Prefab inside a preview/edit context.

Common situations: Scripted Variant refactoring that loads Variant contents and tries to repoint the base Prefab. Batch Variant migration tools that don't account for the preview-scene constraint.

Related errors


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