{"record":{"id":"1d7c46d437a1ef4f","repo":"Unity-Technologies/UnityCsReference","slug":"cyclic-nesting-detected-1d7c46","errorCode":null,"errorMessage":"Cyclic nesting detected","messagePattern":"Cyclic nesting detected","errorType":"exception","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"Editor/Mono/Prefabs/PrefabUtility.cs","lineNumber":2067,"sourceCode":"            string directory = Path.GetDirectoryName(path);\n\n            // We allow relative paths outside the Assets folder so we do not throw if isValidAssetFolder is false\n            bool isRootFolder = false;\n            bool isImmutableFolder = false;\n            bool isValidAssetFolder = AssetDatabase.TryGetAssetFolderInfo(directory, out isRootFolder, out isImmutableFolder);\n\n            if (isValidAssetFolder && isImmutableFolder)\n                throw new ArgumentException(\"Saving Prefab to immutable folder is not allowed: '\" + path + \"'\");\n\n            if (directory.Length > 0 && !Directory.Exists(directory))\n                throw new ArgumentException(\"Given path does not exist: '\" + path + \"'\");\n\n            if (isValidAssetFolder)\n            {\n                string projectRelativePath = Path.IsPathRooted(path) ? FileUtil.GetProjectRelativePath(path) : path;\n                string prefabGUID = AssetDatabase.AssetPathToGUID(projectRelativePath);\n                if (!VerifyNestingFromScript(new GameObject[] { instanceRoot }, prefabGUID, PrefabUtility.GetPrefabInstanceHandle(instanceRoot)))\n                    throw new ArgumentException(\"Cyclic nesting detected\");\n            }\n        }\n\n        private static void SaveAsPrefabAssetArgumentCheck(GameObject instanceRoot, string path, bool connectToInstance)\n        {\n            if (instanceRoot == null)\n                throw new ArgumentNullException(\"Parameter root is null\");\n\n            if (EditorUtility.IsPersistent(instanceRoot) && connectToInstance)\n                throw new ArgumentException(\"Can't save persistent Objects and connect them to the saved Prefab\");\n\n            if (IsPartOfNonAssetPrefabInstance(instanceRoot))\n            {\n                // A PrefabInstance with missing asset can be correctly restored only if CorrespondingObjects info is available\n                // CorrespondingObject info is available when a PrefabInstance with missing asset was merged before deleting the asset (kNormalMerge) or when it has a scene backup (kMergedAsMissingWithSceneBackup)\n                var mergeStatus = GetMergeStatus(instanceRoot);\n                var hasCorrespondingSourceObjectInfo = mergeStatus == MergeStatus.NormalMerge || mergeStatus == MergeStatus.MergedAsMissingWithSceneBackup;\n                if (IsPrefabAssetMissing(instanceRoot) && !hasCorrespondingSourceObjectInfo)","sourceCodeStart":2049,"sourceCodeEnd":2085,"githubUrl":"https://github.com/Unity-Technologies/UnityCsReference/blob/225b0fbdb57cc17d094e8056b71f8314aba56f73/Editor/Mono/Prefabs/PrefabUtility.cs#L2049-L2085","documentation":"Thrown by ValidatePath when VerifyNestingFromScript detects that saving the Prefab would create a cycle — the Prefab would end up nested inside itself, directly or transitively. This prevents infinite recursion in the Prefab hierarchy graph.","triggerScenarios":"Saving a Prefab instance whose root is (or contains a reference back to) the same Prefab asset it corresponds to, so the resulting asset would reference itself as a parent. Occurs when the instanceRoot's prefab GUID equals the GUID of the asset at the target path, or when nested variants create a loop.","commonSituations":"Attempting to save a Prefab over itself from within its own open Prefab edit context. Re-parenting a Prefab under one of its own children. Working with nested Prefab variants and accidentally creating a circular reference.","solutions":["Ensure the target assetPath is different from the instanceRoot's own Prefab source path.","If editing a Prefab in Prefab Mode, save normally rather than calling SaveAsPrefabAsset to a path that resolves to the same asset.","Inspect the hierarchy for any GameObject whose source is the same Prefab being saved and remove the self-reference."],"exampleFix":"// before\n// instanceRoot is an instance of \"Assets/A.prefab\"\nPrefabUtility.SaveAsPrefabAsset(instanceRoot, \"Assets/A.prefab\");\n// after\nPrefabUtility.SaveAsPrefabAsset(instanceRoot, \"Assets/A_variant.prefab\");","handlingStrategy":"validation","validationCode":"bool WouldCauseCycle(GameObject instanceRoot, string targetPath)\n{\n    string projectRelative = Path.IsPathRooted(targetPath)\n        ? FileUtil.GetProjectRelativePath(targetPath) : targetPath;\n    string sourceGuid = AssetDatabase.AssetPathToGUID(projectRelative);\n    var handle = PrefabUtility.GetPrefabInstanceHandle(instanceRoot);\n    return !PrefabUtility.VerifyNestingFromScript(\n        new[] { instanceRoot }, sourceGuid, handle);\n}","typeGuard":"static bool IsSafeNestingTarget(GameObject instanceRoot, string path) =>\n    !WouldCauseCycle(instanceRoot, path);","tryCatchPattern":"try { PrefabUtility.SaveAsPrefabAsset(go, path); }\ncatch (ArgumentException e) when (e.Message.Contains(\"Cyclic nesting\"))\n{ Debug.LogError(\"Cycle detected; choose a different path.\"); }","preventionTips":["Never save a Prefab instance to the same path as its own source asset.","Verify nesting with VerifyNestingFromScript in automated pipelines.","Audit nested Prefab hierarchies for self-references before bulk save."],"tags":["unity","prefab","cyclic-nesting","validation"],"backgroundTag":null,"analyzedSha":"225b0fbdb57cc17d094e8056b71f8314aba56f73","analyzedAt":"2026-08-13T19:07:19.849Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}