Unity-Technologies/UnityCsReference · error · ArgumentException

The asset GameObject cannot be the root as the root cannot b

Error message

The asset GameObject cannot be the root as the root cannot be removed as an override.

What it means

Thrown by ApplyRemovedGameObject when assetGameObject.transform.root == assetGameObject.transform, meaning the supplied asset GameObject is the prefab root. The root can never be a 'removed child' override (the root always exists), so Unity rejects it with ArgumentException. Removing the root is not a valid override operation.

Source

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

            var removedGameObjects = PrefabUtility.GetRemovedGameObjects(prefabInstanceObject);
#pragma warning disable UA2001 // The Banned API Analyzer produces compile errors for any new Linq code. This pre-existing usage has been suppressed, but should be rewritten if possible.
            var filteredRemovedGameObjects = (from go in removedGameObjects where go != null select go).ToArray();
#pragma warning restore UA2001
            PrefabUtility.SetRemovedGameObjects(prefabInstanceObject, filteredRemovedGameObjects);
        }

        public static void ApplyRemovedGameObject(GameObject gameObjectInInstance, GameObject assetGameObject, InteractionMode action)
        {
            DateTime startTime = DateTime.UtcNow;

            ThrowExceptionIfNotValidPrefabInstanceObject(gameObjectInInstance, true);

            if (assetGameObject == null)
                throw new ArgumentNullException(nameof(assetGameObject), "Prefab source must not be null.");
            if (!IsPrefabInstanceObjectOf(gameObjectInInstance, PrefabUtility.GetPrefabAssetHandle(assetGameObject)))
                throw new ArgumentException("Prefab instance must match Prefab source.");
            if (assetGameObject.transform.root == assetGameObject.transform)
                throw new ArgumentException("The asset GameObject cannot be the root as the root cannot be removed as an override.");

            var actionName = "Apply Prefab removed GameObject";
            var prefabInstanceObject = PrefabUtility.GetPrefabInstanceHandle(gameObjectInInstance);
            GameObject prefabInstanceRoot = GetOutermostPrefabInstanceRoot(gameObjectInInstance);

            if (prefabInstanceObject == null)
                throw new ArgumentNullException(nameof(prefabInstanceObject), "Prefab instance must not be null.");

            PrefabUtility.Internal_CallPrefabInstanceApplying(prefabInstanceRoot);

            string assetPath = AssetDatabase.GetAssetPath(assetGameObject);
            GameObject assetRoot = GetRootGameObject(assetGameObject);
            byte[] originalFileContent = null;

            if (action == InteractionMode.UserAction)
            {
                if (!FileUtil.ReadFileContentBinary(assetPath, out originalFileContent, out string errorMessage))
                    Debug.LogError($"No undo was registered when removing GameObject {assetGameObject.name} from {assetRoot.name}. \nError: {errorMessage}", assetRoot);

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Exclude the root: ensure assetGameObject.transform.root != assetGameObject.transform before calling.
  2. Operate on a non-root child of the asset hierarchy that was actually removed from the instance.
  3. If you need to remove the whole instance, use the appropriate instance-removal API, not a removed-child override.

Example fix

// before
PrefabUtility.ApplyRemovedGameObject(instanceGo, assetRootGo, InteractionMode.UserAction);

// after
if (assetGameObject.transform.root != assetGameObject.transform)
    PrefabUtility.ApplyRemovedGameObject(instanceGo, assetGameObject, InteractionMode.UserAction);
Defensive patterns

Strategy: validation

Validate before calling

if (assetGameObject.transform.root == assetGameObject.transform)
{ Debug.LogWarning("Asset GameObject is the prefab root; cannot be a removed-child override."); return; }
PrefabUtility.ApplyRemovedGameObject(gameObjectInInstance, assetGameObject, action);

Type guard

static bool IsNonRootChild(GameObject assetGo)
    => assetGo != null && assetGo.transform.root != assetGo.transform;

Prevention

When it happens

Trigger: Calling ApplyRemovedGameObject with assetGameObject set to the prefab asset's root GameObject; passing the outermost prefab root instead of a child that was actually removed.

Common situations: Tooling that iterates removed GameObjects and accidentally includes the root; passing GetOutermostPrefabInstanceRoot result where a child is required; misunderstanding that removed-child overrides exclude the root.

Related errors


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