Unity-Technologies/UnityCsReference · error · ArgumentException
Must be a persistent asset.
Error message
Must be a persistent asset.
What it means
ArgumentException thrown by ValidateContainer when EditorUtility.IsPersistent(container) returns false. This guard ensures the AudioRandomContainer is a saved asset (e.g. a .asset file in the project) rather than a scene-bound or transient instance, because the undo and element-adding operations rely on asset persistence.
Source
Thrown at Editor/Mono/Audio/AudioRandomContainerExtensions.cs:58
throw new ArgumentNullException(nameof(clips));
if (clips.Length == 0)
throw new ArgumentException("Must not be empty.", nameof(clips));
AddElementsInner(container, clips.Length, (i, element) =>
{
if (clips[i] != null)
element.audioClip = clips[i];
});
}
static void ValidateContainer(AudioRandomContainer container)
{
if (container == null)
throw new ArgumentNullException(nameof(container));
if (!EditorUtility.IsPersistent(container))
throw new ArgumentException("Must be a persistent asset.", nameof(container));
}
static void AddElementsInner(AudioRandomContainer container, int count,
Action<int, AudioContainerElement> configureElement)
{
var undoGroupName = count > 1 ? $"{k_BaseAddElementsUndoName}s" : k_BaseAddElementsUndoName;
Undo.RegisterCompleteObjectUndo(container, undoGroupName);
Undo.SetCurrentGroupName(undoGroupName);
if (container.elements == null)
container.elements = Array.Empty<AudioContainerElement>();
var newElements = new AudioContainerElement[count];
var oldAndNewElements = new AudioContainerElement[container.elements.Length + count];
Array.Copy(container.elements, oldAndNewElements, container.elements.Length);
for (var i = 0; i < count; i++)View on GitHub (pinned to 225b0fbdb5)
Solutions
- Ensure the AudioRandomContainer is saved as a project asset (Create > Audio > Audio Random Container or via AssetDatabase.CreateAsset).
- If the container is scene-based, refactor it to be a persistent asset referenced by the scene.
- Verify with EditorUtility.IsPersistent(container) before calling AddElements.
- Check that AssetDatabase.Contains(container) returns true for the target.
Example fix
// before — container is a scene instance
container.AddElements(clips);
// after — verify persistence first
if (!EditorUtility.IsPersistent(container))
{
Debug.LogError("AudioRandomContainer must be a saved asset, not a scene instance.");
return;
}
container.AddElements(clips); Defensive patterns
Strategy: validation
Validate before calling
// Verify container is a persistent asset before calling AddElements
if (container != null && EditorUtility.IsPersistent(container))
container.AddElements(clips);
else
Debug.LogError("AudioRandomContainer must be a saved project asset."); Type guard
static bool IsPersistentContainer(AudioRandomContainer container)
=> container != null && EditorUtility.IsPersistent(container); Prevention
- Save AudioRandomContainer as a .asset file using AssetDatabase.CreateAsset.
- Avoid using scene-bound or runtime-instantiated containers with editor extensions.
- Check EditorUtility.IsPersistent before calling container modification methods.
- Understand the distinction between scene objects and project assets in Unity editor scripting.
When it happens
Trigger: Calling AddElements on an AudioRandomContainer that exists only in a scene (not saved as a project asset), or on a runtime-instantiated container. EditorUtility.IsPersistent returns false for scene objects and ephemeral instances.
Common situations: Attempting to edit a container that lives in a scene instead of as a ScriptableObject asset, working with runtime-created instances in editor tooling, prefab-embedded containers that are not yet saved as assets, mistaken assumptions about where the container resides.
Related errors
AI-assisted analysis of Unity-Technologies/UnityCsReference@225b0fbdb5 (2026-08-13).
Data as JSON: /api/errors/ea54399ce38c70e4.
Report an issue: GitHub.