Unity-Technologies/UnityCsReference · error · InvalidOperationException
Cannot replace the Prefab instance '{0}' with root transform
Error message
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. What it means
Thrown by ThrowIfInvalidArgumentsForReplacePrefabInstance when prefabInstanceRoot.transform.GetType() != prefabAssetRoot.transform.GetType(). The root Transform type of the target instance and the new Prefab asset must match (e.g. both UnityEngine.Transform, or both RectTransform). A mismatch — typically a UI Canvas RectTransform Prefab being swapped for a 3D Transform Prefab or vice versa — would break the hierarchy.
Source
Thrown at Editor/Mono/Prefabs/PrefabUtility.cs:2261
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
- Ensure both the instance root and the new Prefab asset root use the same Transform type (RectTransform for UI, Transform for 3D).
- Add a guard before the call: if (instanceRoot.transform.GetType() != assetRoot.transform.GetType()) skip or log a warning.
- If the types genuinely differ, restructure one of the Prefabs so the root Transform type matches.
Example fix
// before
PrefabUtility.ReplacePrefabAssetOfPrefabInstance(sceneInstance, newPrefabAsset, mode);
// Fails if one root is RectTransform and the other is Transform
// after
if (sceneInstance.transform.GetType() == newPrefabAsset.transform.GetType())
PrefabUtility.ReplacePrefabAssetOfPrefabInstance(sceneInstance, newPrefabAsset, mode);
else
Debug.LogWarning($"Transform type mismatch: {sceneInstance.name} is {sceneInstance.transform.GetType().Name}, asset is {newPrefabAsset.transform.GetType().Name}"); Defensive patterns
Strategy: validation
Validate before calling
if (prefabInstanceRoot.transform.GetType() != prefabAssetRoot.transform.GetType())
{
Debug.LogError($"Transform type mismatch: {prefabInstanceRoot.transform.GetType().Name} vs {prefabAssetRoot.transform.GetType().Name}");
return;
}
PrefabUtility.ReplacePrefabAssetOfPrefabInstance(prefabInstanceRoot, prefabAssetRoot, mode); Type guard
static bool TransformTypesMatch(GameObject instance, GameObject asset)
{
return instance != null && asset != null
&& instance.transform.GetType() == asset.transform.GetType();
} Prevention
- Separate UI (RectTransform) Prefabs from 3D (Transform) Prefabs in your replacement mapping.
- Add a transform-type guard in generic replace utilities.
When it happens
Trigger: Swapping a UI Prefab (root RectTransform) with a non-UI Prefab (root Transform), or the reverse. Replacing a Prefab whose root uses a custom Transform subclass with one that uses the base Transform.
Common situations: Generic 'replace Prefab' tool that doesn't differentiate UI (Canvas) Prefabs from 3D Prefabs. Art pipeline that regenerates Prefabs with different root structures across versions.
Related errors
- Cannot convert the GameObject '{0}' with root transform of t
- 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
AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13).
Data as JSON: /api/errors/264836b3e8ad1723.
Report an issue: GitHub.