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
- Call PrefabUtility.IsPartOfPrefabAsset(go) before invoking CreateVariant
- If starting from a prefab instance, get the corresponding asset via PrefabUtility.GetCorrespondingObjectFromSource or PrefabUtility.GetPrefabAssetPathOfNearestInstanceRoot
- 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
- Call PrefabUtility.IsPartOfPrefabAsset before CreateVariant
- If starting from a scene instance, resolve the source asset via GetCorrespondingObjectFromSource
- Use AssetDatabase.LoadAssetAtPath<GameObject> to load the prefab asset explicitly
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
- Object to create variant from has to be a Prefab root
- Provided GameObject is not a Prefab instance
- The inputObject is null
- PersistentLocalStorageSize must be between 256 and 4096, but
- guid
AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13).
Data as JSON: /api/errors/3dbfa9e8452cabe6.
Report an issue: GitHub.