stride3d/stride · error · ArgumentException

An asset with the same id

Error message

An asset with the same id [{0}] is already registered with the location [{1}]

What it means

The collection keeps mapIdToPath so each asset id resolves to exactly one location. CheckCanAdd throws when an asset with the same AssetId is already registered — ids must be globally unique since they are the target of asset references.

Solutions

  1. Generate a fresh id for the new asset: item.Id = AssetId.New().
  2. If the asset already exists and you meant an update, look it up by id and update its Asset/Location instead of adding.
  3. Remove the existing entry (package.Assets.RemoveById(id) or ContainsById check) before re-adding.
  4. Guard with package.Assets.ContainsById(item.Id) before calling Add.

Example fix

// before
var clone = new AssetItem(item.Location, item.Asset) { Id = item.Id }; // same id
package.Assets.Add(clone); // throws

// after
var clone = new AssetItem(item.Location, item.Asset) { Id = AssetId.New() };
package.Assets.Add(clone);
Defensive patterns

Strategy: validation

Validate before calling

if (package.Assets.ContainsById(item.Id))
    item.Id = AssetId.New();
package.Assets.Add(item);

Type guard

bool IdIsFree(Package p, AssetId id) => !p.Assets.ContainsById(id);

Try / catch

try { package.Assets.Add(item); }
catch (ArgumentException e) when (e.Message.Contains("same id"))
{ item.Id = AssetId.New(); package.Assets.Add(item); }

Prevention

When it happens

Trigger: Calling package.Assets.Add(item) with an Id that already exists in mapIdToPath — typically re-adding an asset that is already in the collection, or two assets sharing a cloned id.

Common situations: Adding an asset twice (e.g. retry logic that does not remove first); deep-copying assets without generating a new AssetId; loading the same asset into the collection from two sources.

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


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/d07230b4d6391d5c. Report an issue: GitHub.

Appendix: source

Thrown at sources/assets/Stride.Core.Assets/PackageAssetCollection.cs:360

        {
            if (container.AssetNamespace is not null)
            {
                item.Location = location = container.Qualify(location);
            }
            else if (location.IsAbsolute)
            {
                throw new ArgumentException("Asset location [{0}] must be relative and not absolute (not start with '/')".ToFormat(location), nameof(item));
            }
        }

        if (referenceable && mapPathToId.ContainsKey(location))
        {
            throw new ArgumentException("An asset [{0}] with the same location [{1}] is already registered ".ToFormat(mapPathToId[location], location.GetDirectoryAndFileName()), nameof(item));
        }

        if (mapIdToPath.ContainsKey(item.Id))
        {
            throw new ArgumentException("An asset with the same id [{0}] is already registered with the location [{1}]".ToFormat(item.Id, location.GetDirectoryAndFileName()), nameof(item));
        }

        if (location.HasDrive)
        {
            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)

View on GitHub (pinned to 96fad776d2)