Unity-Technologies/UnityCsReference · error · ArgumentException

Input instance root is from a Prefab asset, this is not supp

Error message

Input instance root is from a Prefab asset, this is not supported. Input instance: 

What it means

Thrown by ThrowIfInvalidArgumentsForReplacePrefabInstance when EditorUtility.IsPersistent(prefabInstanceRoot) is true, meaning the object lives in the Asset Database (a .prefab file on disk) rather than being a live instance in a scene. ReplacePrefabAssetOfPrefabInstance operates on scene-level instances only; you cannot feed it a Prefab asset's root GameObject.

Source

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

        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)
                    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."));
            }

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Instantiate the Prefab asset into a scene first, then pass the instantiated root to ReplacePrefabAssetOfPrefabInstance.
  2. If you need to modify a Prefab asset directly, use PrefabUtility.LoadPrefabContents / SaveAsPrefabAsset instead.
  3. Add a guard: if (EditorUtility.IsPersistent(obj)) return; before the call.

Example fix

// before
var assetRoot = AssetDatabase.LoadAssetAtPath<GameObject>("Assets/My.prefab");
PrefabUtility.ReplacePrefabAssetOfPrefabInstance(assetRoot, newAsset, mode);

// after
var instance = (GameObject)PrefabUtility.InstantiatePrefab(assetRoot);
PrefabUtility.ReplacePrefabAssetOfPrefabInstance(instance, newAsset, mode);
Defensive patterns

Strategy: validation

Validate before calling

if (EditorUtility.IsPersistent(prefabInstanceRoot))
{
    Debug.LogError("Cannot use a Prefab asset as instance root; instantiate it first.");
    return;
}
PrefabUtility.ReplacePrefabAssetOfPrefabInstance(prefabInstanceRoot, prefabAssetRoot, mode);

Type guard

static bool IsSceneLevelInstance(GameObject obj)
{
    return obj != null && !EditorUtility.IsPersistent(obj);
}

Prevention

When it happens

Trigger: Loading a Prefab asset via AssetDatabase.LoadAssetAtPath or Resources.Load and passing that asset root directly as the 'instance' argument. Using AssetDatabase.FindAssets to locate Prefabs and then calling replace on the asset objects.

Common situations: Confusion between Prefab assets (stored in the project) and Prefab instances (live in a scene). Code that processes a folder of .prefab files and tries to 'replace' them in-place.

Related errors


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