Unity-Technologies/UnityCsReference · error · ArgumentException
Cyclic nesting detected
Error message
Cyclic nesting detected
What it means
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.
Source
Thrown at Editor/Mono/Prefabs/PrefabUtility.cs:2067
string directory = Path.GetDirectoryName(path);
// We allow relative paths outside the Assets folder so we do not throw if isValidAssetFolder is false
bool isRootFolder = false;
bool isImmutableFolder = false;
bool isValidAssetFolder = AssetDatabase.TryGetAssetFolderInfo(directory, out isRootFolder, out isImmutableFolder);
if (isValidAssetFolder && isImmutableFolder)
throw new ArgumentException("Saving Prefab to immutable folder is not allowed: '" + path + "'");
if (directory.Length > 0 && !Directory.Exists(directory))
throw new ArgumentException("Given path does not exist: '" + path + "'");
if (isValidAssetFolder)
{
string projectRelativePath = Path.IsPathRooted(path) ? FileUtil.GetProjectRelativePath(path) : path;
string prefabGUID = AssetDatabase.AssetPathToGUID(projectRelativePath);
if (!VerifyNestingFromScript(new GameObject[] { instanceRoot }, prefabGUID, PrefabUtility.GetPrefabInstanceHandle(instanceRoot)))
throw new ArgumentException("Cyclic nesting detected");
}
}
private static void SaveAsPrefabAssetArgumentCheck(GameObject instanceRoot, string path, bool connectToInstance)
{
if (instanceRoot == null)
throw new ArgumentNullException("Parameter root is null");
if (EditorUtility.IsPersistent(instanceRoot) && connectToInstance)
throw new ArgumentException("Can't save persistent Objects and connect them to the saved Prefab");
if (IsPartOfNonAssetPrefabInstance(instanceRoot))
{
// A PrefabInstance with missing asset can be correctly restored only if CorrespondingObjects info is available
// 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)
var mergeStatus = GetMergeStatus(instanceRoot);
var hasCorrespondingSourceObjectInfo = mergeStatus == MergeStatus.NormalMerge || mergeStatus == MergeStatus.MergedAsMissingWithSceneBackup;
if (IsPrefabAssetMissing(instanceRoot) && !hasCorrespondingSourceObjectInfo)View on GitHub (pinned to 225b0fbdb5)
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.
Example fix
// before // instanceRoot is an instance of "Assets/A.prefab" PrefabUtility.SaveAsPrefabAsset(instanceRoot, "Assets/A.prefab"); // after PrefabUtility.SaveAsPrefabAsset(instanceRoot, "Assets/A_variant.prefab");
Defensive patterns
Strategy: validation
Validate before calling
bool WouldCauseCycle(GameObject instanceRoot, string targetPath)
{
string projectRelative = Path.IsPathRooted(targetPath)
? FileUtil.GetProjectRelativePath(targetPath) : targetPath;
string sourceGuid = AssetDatabase.AssetPathToGUID(projectRelative);
var handle = PrefabUtility.GetPrefabInstanceHandle(instanceRoot);
return !PrefabUtility.VerifyNestingFromScript(
new[] { instanceRoot }, sourceGuid, handle);
} Type guard
static bool IsSafeNestingTarget(GameObject instanceRoot, string path) =>
!WouldCauseCycle(instanceRoot, path); Try / catch
try { PrefabUtility.SaveAsPrefabAsset(go, path); }
catch (ArgumentException e) when (e.Message.Contains("Cyclic nesting"))
{ Debug.LogError("Cycle detected; choose a different path."); } Prevention
- 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.
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- guid
- prefabInstance
- Provided GameObject is not a Prefab instance
- The inputObject is null
- Given input object is not a prefab asset
AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13).
Data as JSON: /api/errors/1d7c46d437a1ef4f.
Report an issue: GitHub.