Unity-Technologies/UnityCsReference · error · ArgumentException

Can't save part of a Prefab instance as a Prefab

Error message

Can't save part of a Prefab instance as a Prefab

What it means

Thrown by SaveAsPrefabAssetArgumentCheck when GetOutermostPrefabInstanceRoot(instanceRoot) returns a different object than instanceRoot. This means the passed GameObject is a descendant inside a Prefab instance, not the instance's root. Prefab save operations require the outermost root as the entry point.

Source

Thrown at Editor/Mono/Prefabs/PrefabUtility.cs:2093

            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)
                    throw new ArgumentException("Can't save Prefab instance with missing asset and scene backup as a Prefab. You may unpack the instance and save the unpacked GameObjects as a Prefab.");
            }

            var actualInstanceRoot = GetOutermostPrefabInstanceRoot(instanceRoot);
            if (actualInstanceRoot)
            {
                if (actualInstanceRoot != instanceRoot)
                    throw new ArgumentException("Can't save part of a Prefab instance as a Prefab");
            }

            ValidatePath(instanceRoot, path);
        }

        private static void ReplacePrefabArgumentCheck(GameObject root, string path)
        {
            if (root == null)
                throw new ArgumentNullException("Parameter root is null");

            ValidatePath(root, path);
        }

        public static GameObject SaveAsPrefabAsset(GameObject instanceRoot, string assetPath, out bool success)
        {
            SaveAsPrefabAssetArgumentCheck(instanceRoot, assetPath, false);

            return SaveAsPrefabAsset_Internal(instanceRoot, assetPath, out success);

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Get the outermost root first: GameObject root = PrefabUtility.GetOutermostPrefabInstanceRoot(instanceRoot); then pass root.
  2. If you want to save just the child, detach it from the instance (or duplicate it outside the instance) before saving.
  3. Use Selection.activeTransform.root or verify PrefabUtility.IsOutermostPrefabInstanceRoot before calling save.

Example fix

// before
GameObject child = transform.Find("Arm/Hand").gameObject;
PrefabUtility.SaveAsPrefabAsset(child, "Assets/h.prefab");
// after
GameObject root = PrefabUtility.GetOutermostPrefabInstanceRoot(child) ?? child;
PrefabUtility.SaveAsPrefabAsset(root, "Assets/root.prefab");
Defensive patterns

Strategy: validation

Validate before calling

GameObject ResolveRoot(GameObject go)
{
    GameObject outer = PrefabUtility.GetOutermostPrefabInstanceRoot(go);
    return outer != null ? outer : go;
}

Type guard

static bool IsPrefabInstanceRoot(GameObject go) =>
    go != null &&
    PrefabUtility.GetOutermostPrefabInstanceRoot(go) == go;

Prevention

When it happens

Trigger: Passing a child or descendant of a Prefab instance to SaveAsPrefabAsset instead of the instance root. E.g. selecting a nested child in the hierarchy and trying to save it as a standalone Prefab while it's still nested.

Common situations: Developer grabs a specific child via transform.GetChild or Transform.Find and tries to save it directly. Selection.activeGameObject points at a non-root nested object. Misunderstanding of outermost-root semantics in nested Prefabs.

Related errors


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