{"record":{"id":"d08d5f7222acc126","repo":"Unity-Technologies/UnityCsReference","slug":"object-to-create-variant-from-has-to-be-a-prefab-r","errorCode":null,"errorMessage":"Object to create variant from has to be a Prefab root","messagePattern":"Object to create variant from has to be a Prefab root","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"Editor/Mono/Prefabs/PrefabUtility.bindings.cs","lineNumber":234,"sourceCode":"        // Resets the properties of all objects in the prefab, including child game objects and components that were added to the prefab instance\n        [NativeMethod(\"RevertPrefabInstance\", IsFreeFunction = true)]\n        extern private static bool RevertPrefabInstance_Internal([NotNull] GameObject go);\n\n        // Helper function to find the prefab root of an object\n        [FreeFunction]\n        [Obsolete(\"Use GetOutermostPrefabInstanceRoot if source is a Prefab instance or source.transform.root.gameObject if source is a Prefab Asset object.\")]\n        extern public static GameObject FindPrefabRoot([NotNull] GameObject source);\n\n        internal static GameObject CreateVariant(GameObject assetRoot, string path)\n        {\n            if (assetRoot == null)\n                throw new ArgumentNullException(\"The inputObject is null\");\n\n            if (!IsPartOfPrefabAsset(assetRoot))\n                throw new ArgumentException(\"Given input object is not a prefab asset\");\n\n            if (assetRoot.transform.root.gameObject != assetRoot)\n                throw new ArgumentException(\"Object to create variant from has to be a Prefab root\");\n\n            if (path == null)\n                throw new ArgumentNullException(\"The path is null\");\n\n            var assetRootObjectPath = AssetDatabase.GetAssetPath(assetRoot);\n            if (Paths.AreEqual(path, assetRootObjectPath, true))\n                throw new ArgumentException(\"Creating a variant of an object into the source file of the input object is not allowed\");\n\n            if (!Paths.IsValidAssetPath(path, \".prefab\"))\n                throw new ArgumentException(\"Given path is not valid: '\" + path + \"'\");\n\n            return CreateVariant_Internal(assetRoot, path);\n        }\n\n        [NativeMethod(\"CreateVariant\", IsFreeFunction = true)]\n        extern private static GameObject CreateVariant_Internal([NotNull] GameObject original, string path);\n\n        [StaticAccessor(\"PrefabUtilityBindings\", StaticAccessorType.DoubleColon)]","sourceCodeStart":216,"sourceCodeEnd":252,"githubUrl":"https://github.com/Unity-Technologies/UnityCsReference/blob/225b0fbdb57cc17d094e8056b71f8314aba56f73/Editor/Mono/Prefabs/PrefabUtility.bindings.cs#L216-L252","documentation":"PrefabUtility.CreateVariant checks that the provided assetRoot is the root of its prefab (assetRoot.transform.root.gameObject == assetRoot) and throws ArgumentException('Object to create variant from has to be a Prefab root') otherwise. Variants must be created from the top-level GameObject of the prefab file; passing a child object within the prefab hierarchy is not allowed.","triggerScenarios":"Calling CreateVariant with a child GameObject of a prefab asset (e.g., a nested component or sub-object) instead of the prefab's root. Code that passes a specific child found via transform.Find or GetComponentInChildren without navigating to the root first.","commonSituations":"Editor tools that operate on a user-selected child object within a prefab. Code that searches for a specific component and then tries to create a variant from the component's GameObject. Prefab nesting where the code mistakenly grabs a nested prefab child.","solutions":["Navigate to the prefab root before calling CreateVariant: assetRoot = assetRoot.transform.root.gameObject","If starting from a child, use go.transform.root.gameObject to get the root","Verify with PrefabUtility.GetOutermostPrefabInstanceRoot or check that the object has no parent in the prefab hierarchy"],"exampleFix":"// before\nvar variant = PrefabUtility.CreateVariant(childObject, \"Assets/Variant.prefab\");\n\n// after\nGameObject root = childObject.transform.root.gameObject;\nif (PrefabUtility.IsPartOfPrefabAsset(root) && root.transform.root.gameObject == root)\n    var variant = PrefabUtility.CreateVariant(root, \"Assets/Variant.prefab\");","handlingStrategy":"validation","validationCode":"GameObject root = assetRoot.transform.root.gameObject;\nif (root != assetRoot)\n{\n    Debug.LogError(\"CreateVariant requires the prefab root, not a child object.\");\n    return;\n}\n// Safe to call CreateVariant(root, path)","typeGuard":"static bool IsPrefabRoot(GameObject go) =>\n    go != null && PrefabUtility.IsPartOfPrefabAsset(go) && go.transform.root.gameObject == go;","tryCatchPattern":"try { var variant = PrefabUtility.CreateVariant(assetRoot, path); }\ncatch (ArgumentException ex) when (ex.Message == \"Object to create variant from has to be a Prefab root\")\n{ Debug.LogError($\"{assetRoot.name} is not the prefab root. Use transform.root.gameObject.\"); }","preventionTips":["Always navigate to transform.root.gameObject before calling CreateVariant","Validate that the object is the root of its prefab hierarchy","When processing user-selected child objects, resolve the root first"],"tags":["unity","editor-scripting","prefab","validation","prefab-root","prefab-variant","argumentexception"],"backgroundTag":null,"analyzedSha":"225b0fbdb57cc17d094e8056b71f8314aba56f73","analyzedAt":"2026-08-13T19:07:19.849Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}