Unity-Technologies/UnityCsReference · error · InvalidOperationException

Input '{0}' is not a Prefab instance, for plain GameObjects

Error message

Input '{0}' is not a Prefab instance, for plain GameObjects use ConvertToPrefabInstance() instead

What it means

Thrown by ThrowIfInvalidArgumentsForReplacePrefabInstance when the GameObject passed as prefabInstanceRoot is not part of a Prefab instance in a scene (IsPartOfNonAssetPrefabInstance returns false). ReplacePrefabAssetOfPrefabInstance expects an existing Prefab instance to swap its source asset; a plain scene GameObject is not eligible. The message points you to ConvertToPrefabInstance() which is the correct API for turning a plain GameObject into a Prefab instance.

Source

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

            // Recording undo does not handle missing scripts
            var gameObjectsWithInvalidScript = FindGameObjectsWithInvalidComponent(prefabAsset);
            if (action == InteractionMode.UserAction && gameObjectsWithInvalidScript.Count > 0)
                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)
            {

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. If the object is a plain GameObject, call PrefabUtility.ConvertToPrefabInstance() instead.
  2. Branch on PrefabUtility.IsPartOfNonAssetPrefabInstance(obj) before choosing which API to call.
  3. Ensure the object you pass was instantiated from a Prefab asset (e.g. via Instantiate on a loaded Prefab, not new GameObject).

Example fix

// before
PrefabUtility.ReplacePrefabAssetOfPrefabInstance(myGo, prefabAsset, InteractionMode.AutomatedAction);

// after
if (PrefabUtility.IsPartOfNonAssetPrefabInstance(myGo))
    PrefabUtility.ReplacePrefabAssetOfPrefabInstance(myGo, prefabAsset, InteractionMode.AutomatedAction);
else
    PrefabUtility.ConvertToPrefabInstance(myGo, prefabAsset, new ConvertToPrefabInstanceSettings(), InteractionMode.AutomatedAction);
Defensive patterns

Strategy: validation

Validate before calling

// Validate before calling ReplacePrefabAssetOfPrefabInstance
if (!PrefabUtility.IsPartOfNonAssetPrefabInstance(prefabInstanceRoot))
{
    // Use ConvertToPrefabInstance instead, or skip
    PrefabUtility.ConvertToPrefabInstance(prefabInstanceRoot, prefabAssetRoot, new ConvertToPrefabInstanceSettings(), mode);
    return;
}
PrefabUtility.ReplacePrefabAssetOfPrefabInstance(prefabInstanceRoot, prefabAssetRoot, mode);

Type guard

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

Prevention

When it happens

Trigger: Calling PrefabUtility.ReplacePrefabAssetOfPrefabInstance(plainGameObject, prefabAsset, mode) where plainGameObject was never instantiated from a Prefab (e.g. created via new GameObject()). Also happens if the object was previously unpacked with UnpackPrefabInstance and is now a plain scene object.

Common situations: Script that generically applies a 'swap prefab' operation to a selection that mixes plain GameObjects and Prefab instances. Editor automation that assumes a dragged object is always a Prefab instance. Migrating from the legacy ReplacePrefab API where plain GameObjects were sometimes accepted.

Related errors


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