Unity-Technologies/UnityCsReference · error · ArgumentException
Duplicating Assets is unsupported by this function. Use Asse
Error message
Duplicating Assets is unsupported by this function. Use AssetDatabase.CopyAsset to duplicate Assets.
What it means
DuplicateGameObjects rejects persistent objects (assets) because runtime duplication semantics differ from asset duplication; EditorUtility.IsPersistent returns true for assets and the API throws ArgumentException directing you to AssetDatabase.CopyAsset instead. This guard prevents accidental in-place asset cloning that would bypass import/serialization.
Source
Thrown at Editor/Mono/GameObjectUtility.bindings.cs:187
{
return DuplicateGameObjects(gameObjects, true);
}
public static GameObject[] DuplicateGameObjects(GameObject[] gameObjects, bool recordUndo)
{
if (gameObjects == null)
throw new System.ArgumentNullException("gameObjects array is null");
if (gameObjects.Length == 0)
return Array.Empty<GameObject>();
foreach (GameObject go in gameObjects)
{
if (go == null)
throw new System.ArgumentNullException("GameObject in gameObjects array is null");
if (EditorUtility.IsPersistent(go))
throw new System.ArgumentException("Duplicating Assets is unsupported by this function. Use AssetDatabase.CopyAsset to duplicate Assets.");
}
return DuplicateGameObjects_Internal(gameObjects, recordUndo);
}
public static GameObject DuplicateGameObject(GameObject gameObject)
{
return DuplicateGameObject(gameObject, true);
}
public static GameObject DuplicateGameObject(GameObject gameObject, bool recordUndo)
{
if (gameObject == null)
throw new System.ArgumentNullException("gameObject is null");
if (EditorUtility.IsPersistent(gameObject))
throw new System.ArgumentException("Duplicating Assets is unsupported by this function. Use AssetDatabase.CopyAsset to duplicate Assets.");
View on GitHub (pinned to 225b0fbdb5)
Solutions
- For assets, use AssetDatabase.CopyAsset(sourcePath, destPath) instead.
- Pre-filter the array to exclude persistent objects before calling DuplicateGameObjects.
- Instantiate an asset into the scene first (Object.Instantiate) if you want a scene copy, then duplicate.
Example fix
// before
GameObjectUtility.DuplicateGameObjects(new[] { prefabAsset });
// after
AssetDatabase.CopyAsset(AssetDatabase.GetAssetPath(prefabAsset), destPath); Defensive patterns
Strategy: validation
Validate before calling
var sceneOnly = gameObjects.Where(go => !EditorUtility.IsPersistent(go)).ToArray(); if (sceneOnly.Length == 0) return Array.Empty<GameObject>(); return GameObjectUtility.DuplicateGameObjects(sceneOnly, recordUndo);
Type guard
static bool IsSceneObject(GameObject go) => go != null && !EditorUtility.IsPersistent(go);
Prevention
- Branch on EditorUtility.IsPersistent before duplicating.
- Use AssetDatabase.CopyAsset for Project-window assets.
- Keep scene-duplication and asset-copy code paths separate.
When it happens
Trigger: Passing a prefab/asset GameObject (e.g. loaded via AssetDatabase.LoadAssetAtPath) into DuplicateGameObjects; selecting an asset in the Project window and triggering duplicate-via-this-API; batch operations that mix scene objects and assets.
Common situations: Editor tool that duplicates 'objects' generically without distinguishing scene Hierarchy vs Project assets; copy-paste from scene duplication code applied to assets.
Related errors
- Invalid argument: {dropPosition}
- gameObjects array is null
- GameObject in gameObjects array is null
- gameObject is null
- The value ({renderedPickingIndexCount}) must not be negative
AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13).
Data as JSON: /api/errors/2b89ea1c041d4e0b.
Report an issue: GitHub.