stride3d/stride · error · ArgumentException
Cannot add the asset
Error message
Cannot add the asset [{0}] [{1}] to package [{2}] [{3}]: it is already in package [{4}] [{5}] in the current session What it means
Within a Stride editing session, each asset id must exist in exactly one package. CheckCanAdd performs a session-wide scan: if another package in Package.Session.Packages already contains the id, the add is rejected with a message naming both packages, keeping session state consistent for references and undo.
Solutions
- Assign a new id to the duplicated asset: item.Id = AssetId.New() before adding.
- Remove the asset from the other package first if the intent is a move between packages.
- Search the session for the existing owner (otherPackage.Assets[id]) and update it there instead of adding a copy.
- Run the copy/move through session-level package operations rather than raw per-package Add.
Example fix
// before
packageB.Assets.Add(assetItem); // assetItem.Id still owned by packageA
// after
var copy = new AssetItem(assetItem.Location, (Asset)assetItem.Asset.Clone()) { Id = AssetId.New() };
packageB.Assets.Add(copy); Defensive patterns
Strategy: validation
Validate before calling
foreach (var p in package.Session.Packages)
if (p != package && p.Assets.ContainsById(item.Id))
item.Id = AssetId.New();
package.Assets.Add(item); Type guard
bool IdFreeInSession(Package target, AssetId id) =>
target.Session?.Packages.All(p => p == target || !p.Assets.ContainsById(id)) ?? true; Try / catch
try { package.Assets.Add(item); }
catch (ArgumentException e) when (e.Message.Contains("already in package"))
{ item.Id = AssetId.New(); package.Assets.Add(item); } Prevention
- Always regenerate ids when duplicating assets across packages
- Perform cross-package moves through session-level operations
- Run ContainsById checks across the whole session in copy tooling
When it happens
Trigger: Calling package.Assets.Add(item) while Package.Session is non-null and some other package in the session already contains an asset with item.Id (found via ContainsById). The throw uses the constructed formatted message without an paramName argument.
Common situations: Duplicating an asset into another package without regenerating its id; loading the same asset file into two packages of one session; scripted tools that copy assets between packages and forget new ids.
Understand the failure class
Background: "already exists" / EEXIST / FileAlreadyExistsException: what the 'file already exists' error means and how to fix it — this error's family across 37 libraries.
Related errors
- An asset with the same id
- Asset already exist in this collection
- An asset [ ] with the same location [ ] is already…
- Cannot query package with dependencies when it is not…
- Unable to find the base
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/9d7036a90b30e950.
Report an issue: GitHub.
Appendix: source
Thrown at sources/assets/Stride.Core.Assets/PackageAssetCollection.cs:382
{
throw new ArgumentException("Asset location [{0}] cannot contain drive information".ToFormat(location), nameof(item));
}
if (location.GetDirectory()?.StartsWith("..", StringComparison.Ordinal) == true)
{
throw new ArgumentException("Asset location [{0}] cannot start with relative '..'".ToFormat(location), nameof(item));
}
// Double check that this asset is not already stored in another package for this session
if (Package.Session != null)
{
foreach (var otherPackage in Package.Session.Packages)
{
if (otherPackage != Package)
{
if (otherPackage.Assets.ContainsById(item.Id))
{
throw new ArgumentException("Cannot add the asset [{0}] [{1}] to package [{2}] [{3}]: it is already in package [{4}] [{5}] in the current session".ToFormat(item.Id, item.Location, Package.Meta.Name, Package.FullPath, otherPackage.Meta.Name, otherPackage.FullPath));
}
}
}
}
}
public IEnumerator<AssetItem> GetEnumerator()
{
return registeredItems.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
void ICollection.CopyTo(Array array, int index)
{View on GitHub (pinned to 96fad776d2)