Unity-Technologies/UnityCsReference · error · InvalidOperationException
Input '{0}' is not a plain GameObject, it is already a Prefa
Error message
Input '{0}' is not a plain GameObject, it is already a Prefab instance. Use ReplacePrefabAssetOfPrefabInstance() instead. What it means
Thrown by ThrowIfInvalidArgumentsForConvertToPrefabInstance when IsPartOfNonAssetPrefabInstance(plainGameObject) returns true. ConvertToPrefabInstance expects a plain scene GameObject — one that is NOT already a Prefab instance. If the object is already a Prefab instance, the correct API is ReplacePrefabAssetOfPrefabInstance(), which swaps the underlying asset.
Source
Thrown at Editor/Mono/Prefabs/PrefabUtility.cs:2352
if (!success)
{
Debug.LogError(string.Format("Replace Prefab Instance failed for instance '{0}' using asset '{1}' at '{2}'", prefabInstanceRoot.name, prefabAssetRoot.name, AssetDatabase.GetAssetPath(prefabAssetRoot)), prefabInstanceRoot);
}
if (mode == InteractionMode.UserAction)
Undo.FlushTrackedObjects();
}
internal static void ThrowIfInvalidArgumentsForConvertToPrefabInstance(GameObject plainGameObject, GameObject prefabAssetRoot, bool checkValidAsset, InteractionMode mode)
{
if (plainGameObject == null)
throw new ArgumentNullException(nameof(plainGameObject));
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)View on GitHub (pinned to 225b0fbdb5)
Solutions
- If the object is already a Prefab instance, call PrefabUtility.ReplacePrefabAssetOfPrefabInstance() instead.
- Guard with: if (PrefabUtility.IsPartOfNonAssetPrefabInstance(obj)) call Replace; else call Convert.
- Unpack the Prefab instance (UnpackPrefabInstance) first if you truly need to re-convert.
Example fix
// before
PrefabUtility.ConvertToPrefabInstance(myGo, prefabAsset, settings, mode);
// myGo is already a Prefab instance
// after
if (PrefabUtility.IsPartOfNonAssetPrefabInstance(myGo))
PrefabUtility.ReplacePrefabAssetOfPrefabInstance(myGo, prefabAsset, mode);
else
PrefabUtility.ConvertToPrefabInstance(myGo, prefabAsset, settings, mode); Defensive patterns
Strategy: validation
Validate before calling
if (PrefabUtility.IsPartOfNonAssetPrefabInstance(plainGameObject))
{
PrefabUtility.ReplacePrefabAssetOfPrefabInstance(plainGameObject, prefabAssetRoot, mode);
return;
}
PrefabUtility.ConvertToPrefabInstance(plainGameObject, prefabAssetRoot, settings, mode); Type guard
static bool IsPlainSceneGameObject(GameObject obj)
{
return obj != null
&& !PrefabUtility.IsPartOfNonAssetPrefabInstance(obj)
&& !EditorUtility.IsPersistent(obj);
} Prevention
- Branch on IsPartOfNonAssetPrefabInstance to pick Convert vs Replace.
- Track which objects have already been converted to avoid double-processing.
When it happens
Trigger: Calling ConvertToPrefabInstance on a GameObject that was already instantiated from a Prefab (i.e. it is a Prefab instance). E.g. a scene object created via Instantiate(prefabAsset) passed to ConvertToPrefabInstance.
Common situations: Generic 'apply Prefab' code that doesn't distinguish plain GameObjects from existing instances. Re-running a conversion script on objects that were already converted in a previous pass.
Related errors
- Input '{0}' is not a Prefab instance, for plain GameObjects
- Input instance is not an outermost Prefab instance root. Inp
- 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
AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13).
Data as JSON: /api/errors/9719cfbdde5589f1.
Report an issue: GitHub.