Unity-Technologies/UnityCsReference · error · InvalidOperationException
Cannot convert the GameObject '{0}' with root transform of t
Error message
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. What it means
Thrown by ThrowIfInvalidArgumentsForConvertToPrefabInstance when plainGameObject.transform.GetType() != prefabAssetRoot.transform.GetType(). The root Transform of the plain GameObject and the target Prefab asset must be the same type (both Transform or both RectTransform). A mismatch — e.g. converting a 3D object (Transform) to a UI Prefab (RectTransform) — would corrupt the hierarchy.
Source
Thrown at Editor/Mono/Prefabs/PrefabUtility.cs:2361
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)
{
// Recording undo does not handle missing scripts
var gameObjectsWithInvalidScript = FindGameObjectsWithInvalidComponent(plainGameObject);
if (gameObjectsWithInvalidScript.Count > 0)
throw new InvalidOperationException(string.Format($"Cannot convert the GameObject when it has a missing script. GameObject '{gameObjectsWithInvalidScript[0].name}' has a missing script. This is not supported by the Undo system. Use InteractionMode.AutomatedAction instead."));
}
}
public static void ConvertToPrefabInstance(GameObject plainGameObject, GameObject prefabAssetRoot, ConvertToPrefabInstanceSettings settings, InteractionMode mode)View on GitHub (pinned to 225b0fbdb5)
Solutions
- Match the Transform type: use a UI Prefab asset for UI objects (RectTransform) and a 3D Prefab for 3D objects (Transform).
- Guard before calling: if (plainGameObject.transform.GetType() != prefabAssetRoot.transform.GetType()) skip or warn.
- Re-parent or restructure the plain GameObject so its root Transform type matches the target Prefab.
Example fix
// before
PrefabUtility.ConvertToPrefabInstance(plainGo, uiPrefabAsset, settings, mode);
// plainGo root is Transform, uiPrefabAsset root is RectTransform
// after
if (plainGo.transform.GetType() == uiPrefabAsset.transform.GetType())
PrefabUtility.ConvertToPrefabInstance(plainGo, uiPrefabAsset, settings, mode);
else
Debug.LogWarning("Transform type mismatch; cannot convert."); Defensive patterns
Strategy: validation
Validate before calling
if (plainGameObject.transform.GetType() != prefabAssetRoot.transform.GetType())
{
Debug.LogError($"Transform type mismatch: {plainGameObject.transform.GetType().Name} vs {prefabAssetRoot.transform.GetType().Name}");
return;
}
PrefabUtility.ConvertToPrefabInstance(plainGameObject, prefabAssetRoot, settings, mode); Type guard
static bool TransformTypesMatch(GameObject go, GameObject asset)
{
return go != null && asset != null
&& go.transform.GetType() == asset.transform.GetType();
} Prevention
- Maintain separate Prefab catalogs for UI (RectTransform) and 3D (Transform) assets.
- Add a transform-type check to generic conversion utilities.
When it happens
Trigger: Converting a 3D scene object into a UI Canvas Prefab, or a UI element into a 3D Prefab. Using a Prefab asset whose root has a custom Transform subclass against a plain GameObject with a base Transform.
Common situations: Generic conversion tool that doesn't differentiate UI from 3D Prefabs. Art pipeline that changes root structure between Prefab versions.
Related errors
- Cannot replace the Prefab instance '{0}' with root transform
- 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/ea59328aa4723007.
Report an issue: GitHub.