Unity-Technologies/UnityCsReference · error · ArgumentException

Target Prefab has to be a Prefab Asset

Error message

Target Prefab has to be a Prefab Asset

What it means

Thrown by AddGameObjectsToPrefabAndConnect when `targetPrefab` is not null but is not itself a Prefab Asset (PrefabUtility.IsPartOfPrefabAsset returns false). The target must be an asset stored on disk, not a scene instance or a plain GameObject.

Source

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

        extern private static GameObject SaveAsPrefabAssetAndConnect_Internal([NotNull] GameObject root, string path, out bool success);

        [StaticAccessor("PrefabUtilityBindings", StaticAccessorType.DoubleColon)]
        [NativeMethod(ThrowsException = true)]
        extern private static GameObject SavePrefabAsset_Internal([NotNull] GameObject root, out bool success);

        internal static void AddGameObjectsToPrefabAndConnect(GameObject[] gameObjects, Object targetPrefab)
        {
            if (gameObjects == null)
                throw new ArgumentNullException("gameObjects");

            if (gameObjects.Length == 0)
                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)

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Pass the Prefab Asset root from the Project window, e.g. loaded via AssetDatabase.LoadAssetAtPath<GameObject>.
  2. Verify with PrefabUtility.IsPartOfPrefabAsset(targetPrefab) before calling.
  3. If you only have an instance, resolve its source asset via PrefabUtility.GetCorrespondingObjectFromSource / GetPrefabAssetHandle and pass that.

Example fix

// before
GameObject target = Selection.activeGameObject; // a scene instance
PrefabUtility.AddGameObjectsToPrefabAndConnect(gos, target); // throws

// after
GameObject target = Selection.activeGameObject;
if (!PrefabUtility.IsPartOfPrefabAsset(target))
    target = PrefabUtility.GetCorrespondingObjectFromSource(target);
if (!PrefabUtility.IsPartOfPrefabAsset(target))
    throw new ArgumentException("Target is not a prefab asset.");
PrefabUtility.AddGameObjectsToPrefabAndConnect(gos, target);
Defensive patterns

Strategy: validation

Validate before calling

if (targetPrefab == null || !PrefabUtility.IsPartOfPrefabAsset(targetPrefab))
    throw new ArgumentException("Target must be a prefab asset on disk.", nameof(targetPrefab));

Type guard

static bool IsPrefabAsset(GameObject obj) => obj != null && PrefabUtility.IsPartOfPrefabAsset(obj);

Prevention

When it happens

Trigger: Passing a scene instance of a prefab, a disconnected prefab instance, a regular non-prefab GameObject, or a prefab that is an instance/variant-in-scene rather than the asset root.

Common situations: Grabbing the target via Selection.activeGameObject while a scene instance (not the asset) is selected. Using the root of an open Prefab edit stage incorrectly. Passing a PrefabAssetHandle/Component instead of the prefab GameObject asset.

Related errors


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