Unity-Technologies/UnityCsReference · error · ArgumentNullException
prefabAssetRoot
Error message
prefabAssetRoot
What it means
Thrown by ThrowIfInvalidArgumentsForReplacePrefabInstance when prefabAssetRoot is null. This is the second null guard (after prefabInstanceRoot), ensuring both the instance and the replacement asset are non-null before proceeding to the detailed asset-validity checks.
Source
Thrown at Editor/Mono/Prefabs/PrefabUtility.cs:2243
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));
if (EditorUtility.IsPersistent(prefabInstanceRoot))
throw new ArgumentException("Input instance root is from a Prefab asset, this is not supported. Input instance: " + prefabInstanceRoot.name, nameof(prefabInstanceRoot));
if (PrefabStageUtility.IsGameObjectThePrefabRootInAnyPrefabStage(prefabInstanceRoot))
throw new InvalidOperationException("Replacing the root Prefab instance in a Variant is not supported since it will break all overrides for existing instances of this Variant, including their positions and rotations." + prefabInstanceRoot.name);
if (IsAnyPrefabInstanceRoot(prefabInstanceRoot) && EditorSceneManager.IsPreviewSceneObject(prefabInstanceRoot) && prefabInstanceRoot.transform.parent == null) // EditPrefabContentsScope handling
throw new InvalidOperationException("Replacing the Variant parent is not supported since it will break all overrides for existing instances of this Variant, including their positions and rotations." + prefabInstanceRoot.name);
if (prefabInstanceRoot.transform.GetType() != prefabAssetRoot.transform.GetType())
throw new InvalidOperationException(string.Format("Cannot replace the Prefab instance '{0}' with root transform of type {1} with a Prefab asset with root transform of type {2}. Transform types must match.", prefabInstanceRoot.name, prefabInstanceRoot.transform.GetType().Name, prefabAssetRoot.transform.GetType().Name));View on GitHub (pinned to 225b0fbdb5)
Solutions
- Null-check prefabAssetRoot before calling the replace API.
- Validate the asset path string and existence with AssetDatabase.LoadAssetAtPath before calling.
- Re-resolve the asset after any AssetDatabase.Refresh.
Example fix
// before
GameObject assetRoot = AssetDatabase.LoadAssetAtPath<GameObject>(path);
ThrowIfInvalidArgumentsForReplacePrefabInstance(instanceRoot, assetRoot, true, mode);
// after
GameObject assetRoot = AssetDatabase.LoadAssetAtPath<GameObject>(path);
if (assetRoot == null) { Debug.LogError("Missing asset: " + path); return; }
ThrowIfInvalidArgumentsForReplacePrefabInstance(instanceRoot, assetRoot, true, mode); Defensive patterns
Strategy: type-guard
Validate before calling
if (prefabAssetRoot == null)
{ Debug.LogError("prefabAssetRoot is null; verify the asset path."); return; }
PrefabUtility.ThrowIfInvalidArgumentsForReplacePrefabInstance(instanceRoot, prefabAssetRoot, checkValidAsset, mode); Type guard
static bool AreReplaceArgsValid(GameObject instance, GameObject asset) =>
instance != null && asset != null; Prevention
- Null-check both instance and asset root before calling replace.
- Validate asset paths with LoadAssetAtPath before replace.
- Re-resolve references after any AssetDatabase operation.
When it happens
Trigger: Calling ReplacePrefabInstance (internal) with prefabAssetRoot == null, usually from a failed asset lookup or an unassigned reference.
Common situations: AssetDatabase.LoadAssetAtPath returned null. A serialized Prefab reference was not assigned. The asset was renamed or moved between lookup and the replace call.
Related errors
- Value cannot be null. (Parameter 'prefabAsset')
- Parameter root is null
- Value cannot be null. (Parameter 'instance')
- Input Prefab asset is not an asset object. Input asset: {pre
- Cannot replace the Prefab instance since the Prefab Asset is
AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13).
Data as JSON: /api/errors/d8e138800b6a0c6d.
Report an issue: GitHub.