Unity-Technologies/UnityCsReference · error · ArgumentException

Can't save a Prefab instance

Error message

Can't save a Prefab instance

What it means

SavePrefabAsset requires an asset that has a valid asset path (a saved prefab on disk). If AssetDatabase.GetAssetPath returns null or empty, the object is not a saved prefab asset — typically it is a live prefab instance in a scene — and saving is rejected with ArgumentException.

Source

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

            bool savedSuccesfully;
            return SavePrefabAsset(asset, out savedSuccesfully);
        }

        public static GameObject SavePrefabAsset(GameObject asset, out bool savedSuccessfully)
        {
            if (asset == null)
                throw new ArgumentNullException("Parameter prefabAssetGameObject is null");

            // Include model check even though models are also immutable, since we can give a more clear exception message.
            if (IsPartOfModelPrefab(asset))
                throw new ArgumentException("Can't save a Model Prefab");

            if (IsPartOfImmutablePrefab(asset))
                throw new ArgumentException("Can't save an immutable Prefab");

            string path = AssetDatabase.GetAssetPath(asset);
            if (String.IsNullOrEmpty(path))
                throw new ArgumentException("Can't save a Prefab instance");

            var root = asset.transform.root.gameObject;
            if (root != asset)
                throw new ArgumentException("GameObject to save Prefab from must be a Prefab root");

            return SavePrefabAsset_Internal(root, out savedSuccessfully);
        }

        internal static void ValidatePath(GameObject instanceRoot, string path)
        {
            if (String.IsNullOrEmpty(path))
                throw new ArgumentNullException("path is null or empty");

            if (!Paths.IsValidAssetPath(path, ".prefab"))
                throw new ArgumentException("Given path is not valid: '" + path + "'");

            if (Directory.Exists(path))
                throw new ArgumentException("Overwriting a folder with an Asset is not allowed: '" + path + "'");

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Use PrefabUtility.SaveAsPrefabAsset(instance, path) for instances in scenes.
  2. Resolve the asset on disk (via GetPrefabAssetHandle / asset path) before calling SavePrefabAsset.
  3. Check !string.IsNullOrEmpty(AssetDatabase.GetAssetPath(asset)) before saving.

Example fix

// before
PrefabUtility.SavePrefabAsset(sceneInstance);

// after
if (!string.IsNullOrEmpty(AssetDatabase.GetAssetPath(sceneInstance)))
    PrefabUtility.SavePrefabAsset(sceneInstance);
else
    PrefabUtility.SaveAsPrefabAsset(sceneInstance, "Assets/Saved.prefab");
Defensive patterns

Strategy: validation

Validate before calling

string path = AssetDatabase.GetAssetPath(asset);
if (string.IsNullOrEmpty(path)) return; // it is an instance, not an asset

Type guard

static bool IsSavedPrefabAsset(GameObject asset) =>
    asset != null && !string.IsNullOrEmpty(AssetDatabase.GetAssetPath(asset));

Prevention

When it happens

Trigger: Calling SavePrefabAsset on a prefab instance that exists in a scene rather than a prefab asset on disk; passing a runtime/unsaved object.

Common situations: Confusing an instance in the scene with the asset on disk; selecting a prefab instance and expecting SavePrefabAsset to persist it.

Related errors


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