Unity-Technologies/UnityCsReference · error · ArgumentException

Given input object is not a prefab asset

Error message

Given input object is not a prefab asset

What it means

PrefabUtility.CreateVariant checks that the provided assetRoot is part of a prefab asset (PrefabUtility.IsPartOfPrefabAsset returns true) and throws ArgumentException('Given input object is not a prefab asset') otherwise. This ensures the variant source is an actual prefab saved in the project, not a scene object or a prefab instance in a scene. Variants can only derive from prefab assets.

Source

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

        [FreeFunction]
        extern public static bool RevertPrefabInstance([NotNull] GameObject go);

        // Resets the properties of all objects in the prefab, including child game objects and components that were added to the prefab instance
        [NativeMethod("RevertPrefabInstance", IsFreeFunction = true)]
        extern private static bool RevertPrefabInstance_Internal([NotNull] GameObject go);

        // Helper function to find the prefab root of an object
        [FreeFunction]
        [Obsolete("Use GetOutermostPrefabInstanceRoot if source is a Prefab instance or source.transform.root.gameObject if source is a Prefab Asset object.")]
        extern public static GameObject FindPrefabRoot([NotNull] GameObject source);

        internal static GameObject CreateVariant(GameObject assetRoot, string path)
        {
            if (assetRoot == null)
                throw new ArgumentNullException("The inputObject is null");

            if (!IsPartOfPrefabAsset(assetRoot))
                throw new ArgumentException("Given input object is not a prefab asset");

            if (assetRoot.transform.root.gameObject != assetRoot)
                throw new ArgumentException("Object to create variant from has to be a Prefab root");

            if (path == null)
                throw new ArgumentNullException("The path is null");

            var assetRootObjectPath = AssetDatabase.GetAssetPath(assetRoot);
            if (Paths.AreEqual(path, assetRootObjectPath, true))
                throw new ArgumentException("Creating a variant of an object into the source file of the input object is not allowed");

            if (!Paths.IsValidAssetPath(path, ".prefab"))
                throw new ArgumentException("Given path is not valid: '" + path + "'");

            return CreateVariant_Internal(assetRoot, path);
        }

        [NativeMethod("CreateVariant", IsFreeFunction = true)]

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Call PrefabUtility.IsPartOfPrefabAsset(go) before invoking CreateVariant
  2. If starting from a prefab instance, get the corresponding asset via PrefabUtility.GetCorrespondingObjectFromSource or PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot
  3. Use AssetDatabase.LoadAssetAtPath to load the prefab asset explicitly before creating a variant

Example fix

// before
var variant = PrefabUtility.CreateVariant(sceneInstance, "Assets/Variant.prefab");

// after
GameObject assetRoot = PrefabUtility.IsPartOfPrefabAsset(go) ? go : AssetDatabase.LoadAssetAtPath<GameObject>(PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot(go));
if (assetRoot != null && PrefabUtility.IsPartOfPrefabAsset(assetRoot))
    var variant = PrefabUtility.CreateVariant(assetRoot, "Assets/Variant.prefab");
Defensive patterns

Strategy: validation

Validate before calling

if (!PrefabUtility.IsPartOfPrefabAsset(assetRoot))
{
    Debug.LogError("CreateVariant requires a prefab asset, not a scene object or instance.");
    return;
}
// Safe to call CreateVariant(assetRoot, path)

Type guard

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

Try / catch

try { var variant = PrefabUtility.CreateVariant(assetRoot, path); }
catch (ArgumentException ex) when (ex.Message == "Given input object is not a prefab asset")
{ Debug.LogError($"{assetRoot?.name} is not a prefab asset. Load via AssetDatabase.LoadAssetAtPath."); }

Prevention

When it happens

Trigger: Calling CreateVariant with a scene-level GameObject, a prefab instance (not the asset), or any object that is not part of a prefab asset file. Passing a runtime-instantiated prefab instead of the asset reference.

Common situations: Editor tools that operate on Selection.activeGameObject (which could be a scene instance, not the asset). Code that confuses prefab instances with prefab assets. Automation that receives objects from scene traversal rather than AssetDatabase lookups.

Related errors


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