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
- Use a user-authored Prefab asset stored under Assets/ as the replacement source.
- Check AssetDatabase.GetAssetPath(asset).StartsWith("Library/") before calling and reject such assets.
- 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
- Only pass user-authored Assets/ Prefabs to replace operations.
- Check the asset path prefix before calling replace.
- Copy built-in/Library resources into Assets/ if a template is needed.
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
- Value cannot be null. (Parameter 'prefabAsset')
- Input Prefab asset is not an asset object. Input asset: {pre
- Cannot replace the Prefab instance with the Prefab Asset '{A
- prefabAssetRoot
- PrefabFamilyPopup is already open
AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13).
Data as JSON: /api/errors/cffa56b96290e7da.
Report an issue: GitHub.