Unity-Technologies/UnityCsReference · error · InvalidOperationException

Cannot replace the Prefab instance since the Prefab Asset is

Error message

Cannot replace the Prefab instance since the Prefab Asset is invalid for instance replacement. Prefab Asset path: {assetPath}

What it means

Thrown by ThrowIfInvalidAssetForReplacePrefabInstance when the Prefab asset's path starts with "Library/". Assets under Library/ are generated/cached by Unity (not user-authored) and are not valid as replacement sources for a Prefab instance.

Source

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

            return InstantiatePrefab_internal(assetComponentOrGameObject, destinationScene, null);
        }

        public static Object InstantiatePrefab(Object assetComponentOrGameObject, Transform parent)
        {
            return InstantiatePrefab_internal(assetComponentOrGameObject, EditorSceneManager.GetTargetSceneForNewGameObjects(), parent);
        }

        internal static void ThrowIfInvalidAssetForReplacePrefabInstance(GameObject prefabAsset, InteractionMode action)
        {
            if (prefabAsset == null)
                throw new ArgumentNullException(nameof(prefabAsset));

            if (!EditorUtility.IsPersistent(prefabAsset))
                throw new ArgumentException("Input Prefab asset is not an asset object. Input asset: " + prefabAsset.name, nameof(prefabAsset));

            var assetPath = AssetDatabase.GetAssetPath(prefabAsset);
            if (assetPath.StartsWith("Library/"))
                throw new InvalidOperationException(string.Format("Cannot replace the Prefab instance since the Prefab Asset is invalid for instance replacement. Prefab Asset path: " + assetPath));

            // Recording undo does not handle missing scripts
            var gameObjectsWithInvalidScript = FindGameObjectsWithInvalidComponent(prefabAsset);
            if (action == InteractionMode.UserAction && gameObjectsWithInvalidScript.Count > 0)
                throw new InvalidOperationException(string.Format($"Cannot replace the Prefab instance with the Prefab Asset '{AssetDatabase.GetAssetPath(prefabAsset)}' because it has a missing script. GameObject '{gameObjectsWithInvalidScript[0].name}' in the Prefab Asset has a missing script."));
        }

        internal static void ThrowIfInvalidArgumentsForReplacePrefabInstance(GameObject prefabInstanceRoot, GameObject prefabAssetRoot, bool checkValidAsset, InteractionMode mode)
        {
            if (prefabInstanceRoot == null)
                throw new ArgumentNullException(nameof(prefabInstanceRoot));

            if (prefabAssetRoot == null)
                throw new ArgumentNullException(nameof(prefabAssetRoot));

            if (checkValidAsset)
                ThrowIfInvalidAssetForReplacePrefabInstance(prefabAssetRoot, mode);

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Use a user-authored Prefab asset stored under Assets/ as the replacement source.
  2. Check AssetDatabase.GetAssetPath(asset).StartsWith("Library/") before calling and reject such assets.
  3. If you need a built-in as a template, copy it into Assets/ first via AssetDatabase.CopyAsset.

Example fix

// before
ThrowIfInvalidAssetForReplacePrefabInstance(libraryAsset, mode);
// after
string srcPath = AssetDatabase.GetAssetPath(libraryAsset);
string dstPath = "Assets/MyCopy.prefab";
AssetDatabase.CopyAsset(srcPath, dstPath);
GameObject goodAsset = AssetDatabase.LoadAssetAtPath<GameObject>(dstPath);
ThrowIfInvalidAssetForReplacePrefabInstance(goodAsset, mode);
Defensive patterns

Strategy: validation

Validate before calling

string assetPath = AssetDatabase.GetAssetPath(prefabAsset);
if (assetPath.StartsWith("Library/"))
{ Debug.LogError("Cannot use Library/ asset for replace: " + assetPath); return; }

Type guard

static bool IsUserAuthoredAsset(GameObject asset)
{
    if (asset == null) return false;
    string p = AssetDatabase.GetAssetPath(asset);
    return !p.StartsWith("Library/");
}

Prevention

When it happens

Trigger: The prefabAsset resolves to an asset whose AssetDatabase.GetAssetPath returns a Library/-prefixed path (e.g. a built-in default resource or a generated cache asset).

Common situations: Passing a built-in Unity resource (stored under Library/) as a replacement asset. Using an asset from a transient import cache. The asset path changed to Library/ after a reimport or cache migration.

Related errors


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