Unity-Technologies/UnityCsReference · error · ArgumentException

UnpackPrefabInstance must be called with a root Prefab insta

Error message

UnpackPrefabInstance must be called with a root Prefab instance GameObject.

What it means

PrefabUtility.UnpackPrefabInstance throws an ArgumentException when instanceRoot is not the outermost root of a prefab instance. The method only accepts the top-level GameObject of a prefab instance, not nested children inside one.

Source

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

            prefabInstanceReverted?.Invoke(instanceRoot);
        }

        [AutoStaticsCleanupOnCodeReload]
        public static event Action<GameObject, PrefabUnpackMode> prefabInstanceUnpacking;
        [AutoStaticsCleanupOnCodeReload]
        public static event Action<GameObject, PrefabUnpackMode> prefabInstanceUnpacked;

        public static void UnpackPrefabInstance(GameObject instanceRoot, PrefabUnpackMode unpackMode, InteractionMode action)
        {
            if (instanceRoot == null)
                throw new ArgumentNullException(nameof(instanceRoot));

            if (!IsPartOfNonAssetPrefabInstance(instanceRoot))
                throw new ArgumentException("UnpackPrefabInstance must be called with a Prefab instance.");

            if (!IsOutermostPrefabInstanceRoot(instanceRoot))
                throw new ArgumentException("UnpackPrefabInstance must be called with a root Prefab instance GameObject.");

            if (action == InteractionMode.UserAction)
            {
                var undoActionName = "Unpack Prefab instance";
                Undo.RegisterFullObjectHierarchyUndo(instanceRoot, undoActionName);
                var newInstanceRoots = UnpackPrefabInstanceAndReturnNewOutermostRoots(instanceRoot, unpackMode);
                foreach (var newInstanceRoot in newInstanceRoots)
                {
                    var prefabInstance = PrefabUtility.GetPrefabInstanceHandle(newInstanceRoot);
                    if (prefabInstance)
                    {
                        Undo.RegisterCreatedObjectUndo(prefabInstance, undoActionName);
                    }
                }
            }
            else
            {
                UnpackPrefabInstanceAndReturnNewOutermostRoots(instanceRoot, unpackMode);

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Find the outermost root first: var root = PrefabUtility.GetOutermostInstanceRoot(go) and pass that.
  2. Use PrefabUtility.IsOutermostPrefabInstanceRoot(go) to verify before unpacking.
  3. When processing from child references, walk up: while (go.transform.parent != null && IsPartOfNonAssetPrefabInstance(go.transform.parent.gameObject)) go = go.transform.parent.gameObject.

Example fix

// before
PrefabUtility.UnpackPrefabInstance(nestedChildGo, PrefabUnpackMode.OutermostRoot, InteractionMode.UserAction);
// after
var root = PrefabUtility.GetOutermostInstanceRoot(go);
if (root != null)
    PrefabUtility.UnpackPrefabInstance(root, PrefabUnpackMode.OutermostRoot, InteractionMode.UserAction);
Defensive patterns

Strategy: validation

Validate before calling

var root = PrefabUtility.GetOutermostInstanceRoot(go);
if (root != null)
    PrefabUtility.UnpackPrefabInstance(root, mode, action);

Type guard

static bool IsOuterRoot(GameObject go) => go != null && PrefabUtility.IsOutermostPrefabInstanceRoot(go);

Prevention

When it happens

Trigger: Calling UnpackPrefabInstance with a child GameObject inside a prefab instance rather than the instance root. Also occurs when multiple nested prefab instances exist and you pass an inner instance root instead of the outermost one.

Common situations: Developer selected a nested prefab instance child, or iterated the hierarchy and passed a deep child rather than finding the outermost root. Common with nested prefabs introduced in Unity 2018.3+.

Related errors


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