Unity-Technologies/UnityCsReference · error · InvalidOperationException

Cannot replace the Prefab instance with the Prefab Asset '{A

Error message

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.

What it means

Thrown by ThrowIfInvalidAssetForReplacePrefabInstance in UserAction mode when the Prefab asset contains one or more GameObjects with missing scripts (MonoBehaviour components whose script class cannot be resolved). Undo recording cannot handle missing scripts, so the replace is blocked during a user action to prevent corruption.

Source

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

            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);

            if (!IsPartOfNonAssetPrefabInstance(prefabInstanceRoot))
                throw new InvalidOperationException(string.Format("Input '{0}' is not a Prefab instance, for plain GameObjects use ConvertToPrefabInstance() instead", prefabInstanceRoot.name));

            if (!IsOutermostPrefabInstanceRoot(prefabInstanceRoot))
                throw new ArgumentException("Input instance is not an outermost Prefab instance root. Input instance: " + prefabInstanceRoot.name, nameof(prefabInstanceRoot));

View on GitHub (pinned to 225b0fbdb5)

Solutions

  1. Fix the missing scripts in the Prefab asset: reassign the correct MonoBehaviour or remove the broken component.
  2. Use InteractionMode.AutomatedAction if you intentionally accept missing scripts (note: undo will not be recorded).
  3. Audit the asset with FindGameObjectsWithInvalidComponent before attempting replace.

Example fix

// before
ThrowIfInvalidAssetForReplacePrefabInstance(asset, InteractionMode.UserAction);
// after
var bad = PrefabUtility.FindGameObjectsWithInvalidComponent(asset);
if (bad.Count > 0)
    Debug.LogError("Fix missing scripts on: " + bad[0].name);
else
    ThrowIfInvalidAssetForReplacePrefabInstance(asset, InteractionMode.UserAction);
Defensive patterns

Strategy: validation

Validate before calling

var invalid = PrefabUtility.FindGameObjectsWithInvalidComponent(prefabAsset);
if (invalid.Count > 0)
{ Debug.LogError("Prefab has missing scripts: " + invalid[0].name); return; }
PrefabUtility.ThrowIfInvalidAssetForReplacePrefabInstance(prefabAsset, InteractionMode.UserAction);

Type guard

static bool HasNoMissingScripts(GameObject asset)
{
    if (asset == null) return false;
    return PrefabUtility.FindGameObjectsWithInvalidComponent(asset).Count == 0;
}

Try / catch

try { PrefabUtility.ThrowIfInvalidAssetForReplacePrefabInstance(asset, InteractionMode.UserAction); }
catch (InvalidOperationException e) when (e.Message.Contains("missing script"))
{ Debug.LogError("Fix missing scripts before replace."); }

Prevention

When it happens

Trigger: Calling ReplacePrefabInstance with InteractionMode.UserAction where FindGameObjectsWithInvalidComponent(prefabAsset) returns a non-empty list. The missing-script check is skipped for non-UserAction modes (automated action).

Common situations: A script was deleted or renamed without updating the Prefab asset. Script GUID changed after a package update or namespace rename. Prefab imported from another project referencing scripts not present.

Related errors


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