Unity-Technologies/UnityCsReference · error · ArgumentException

GameObject is not (directly) parented under a target Prefab

Error message

GameObject is not (directly) parented under a target Prefab instance.

What it means

Thrown when GetParentPrefabInstance(go) returns null, meaning the GameObject is not directly parented under any Prefab instance in the scene hierarchy. Each go must live inside (be a child of) a prefab instance to be connected into a target prefab.

Source

Thrown at Editor/Mono/Prefabs/PrefabUtility.bindings.cs:299

            if (!PrefabUtility.IsPartOfPrefabAsset(targetPrefab))
                throw new ArgumentException("Target Prefab has to be a Prefab Asset");

            Object targetPrefabInstance = null;

            var targetPrefabObject = PrefabUtility.GetPrefabAssetHandle(targetPrefab);

            foreach (GameObject go in gameObjects)
            {
                if (go == null)
                    throw new ArgumentException("GameObject in input 'gameObjects' array is null");

                if (EditorUtility.IsPersistent(go))  // Prefab asset
                    throw new ArgumentException("Game object is part of a prefab");

                var parentPrefabInstance = GetParentPrefabInstance(go);
                if (parentPrefabInstance == null)
                    throw new ArgumentException("GameObject is not (directly) parented under a target Prefab instance.");

                if (targetPrefabInstance == null)
                {
                    targetPrefabInstance = parentPrefabInstance;
                    if (!IsPrefabInstanceObjectOf(go.transform.parent, targetPrefabObject))
                        throw new ArgumentException("GameObject is not parented under a target Prefab instance.");
                }
                else
                {
                    if (parentPrefabInstance != targetPrefabInstance)
                    {
                        throw new ArgumentException("GameObjects must be parented under the same Prefab instance.");
                    }
                }

                if (PrefabUtility.IsPartOfNonAssetPrefabInstance(go))
                {
                    var correspondingGO = PrefabUtility.GetCorrespondingObjectFromSource(go);

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Parent the GameObject under an existing Prefab instance in the scene before calling.
  2. Instantiate via PrefabUtility.InstantiatePrefab so the object is part of an instance.
  3. Filter to objects whose ancestor chain includes a prefab instance root.

Example fix

// before
var go = new GameObject("Loose");
PrefabUtility.AddGameObjectsToPrefabAndConnect(new[]{ go }, target); // not under instance

// after
var instance = (GameObject)PrefabUtility.InstantiatePrefab(target);
go.transform.SetParent(instance.transform);
PrefabUtility.AddGameObjectsToPrefabAndConnect(new[]{ go }, target);
Defensive patterns

Strategy: validation

Validate before calling

gameObjects = gameObjects
    .Where(g => PrefabUtility.GetOutermostPrefabInstanceRoot(g) != null)
    .ToArray();

Prevention

When it happens

Trigger: Passing a top-level scene object that is not inside any prefab instance, or an object whose chain to a prefab root is broken/disconnected. A loose GameObject placed directly in the scene root.

Common situations: Objects created via new GameObject() in the scene then passed in. Objects reparented out of a prefab instance. Prefab instances that were unpacked, severing the instance link.

Related errors


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