Unity-Technologies/UnityCsReference · error · ArgumentException

Game object is part of a prefab

Error message

Game object is part of a prefab

What it means

Thrown when an element `go` in the gameObjects array is persistent (EditorUtility.IsPersistent(go) is true), meaning it is already part of a prefab asset on disk rather than a live scene object. AddGameObjectsToPrefabAndConnect only operates on scene instances, not assets.

Source

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

                throw new ArgumentException("gameObjects array is empty");

            if (targetPrefab == null)
                throw new ArgumentNullException("targetPrefab");

            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.");
                    }
                }

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Pass only scene-based GameObject instances, not assets from the Project window.
  2. Filter out persistent objects: gos.Where(g => !EditorUtility.IsPersistent(g)).
  3. If you intended to nest an existing prefab, use a different API (e.g. PrefabUtility.InstantiatePrefab into the scene first).

Example fix

// before
GameObject[] gos = Selection.objects.OfType<GameObject>().ToArray(); // includes assets
PrefabUtility.AddGameObjectsToPrefabAndConnect(gos, target);

// after
GameObject[] gos = Selection.gameObjects
    .Where(g => g != null && !EditorUtility.IsPersistent(g) && g.scene.IsValid())
    .ToArray();
PrefabUtility.AddGameObjectsToPrefabAndConnect(gos, target);
Defensive patterns

Strategy: validation

Validate before calling

gameObjects = gameObjects
    .Where(g => g != null && !UnityEditor.EditorUtility.IsPersistent(g))
    .ToArray();

Type guard

static bool IsSceneInstance(GameObject g) => g != null && !UnityEditor.EditorUtility.IsPersistent(g) && g.scene.IsValid();

Prevention

When it happens

Trigger: Passing a GameObject that lives in the Project view (a prefab asset) rather than in a scene. Mixing project-prefab objects into the array alongside scene objects.

Common situations: User multi-selected objects from both the Hierarchy (scene) and Project (assets). Editor scripts that iterate AssetDatabase.FindAssets results and feed asset GameObjects directly. Dragging prefab assets into a list used for connecting scene objects.

Related errors


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