{"record":{"id":"9973867f4d18985a","repo":"stride3d/stride","slug":"an-asset-0-with-the-same-location-1-is-already-registered","errorCode":null,"errorMessage":"An asset [{0}] with the same location [{1}] is already registered ","messagePattern":"An asset \\[(.+?)\\] with the same location \\[(.+?)\\] is already registered ","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"sources/assets/Stride.Core.Assets/PackageAssetCollection.cs","lineNumber":355,"sourceCode":"        // unqualified locations, qualified here like the loaders do. Plain packages stay\n        // relative-only (that reservation is what makes rooted URLs collision-free).\n        // Detached packages (clones, pack-time copies) have no container: locations pass through.\n        var location = item.Location;\n        if (Package.Container is { } container)\n        {\n            if (container.AssetNamespace is not null)\n            {\n                item.Location = location = container.Qualify(location);\n            }\n            else if (location.IsAbsolute)\n            {\n                throw new ArgumentException(\"Asset location [{0}] must be relative and not absolute (not start with '/')\".ToFormat(location), nameof(item));\n            }\n        }\n\n        if (referenceable && mapPathToId.ContainsKey(location))\n        {\n            throw new ArgumentException(\"An asset [{0}] with the same location [{1}] is already registered \".ToFormat(mapPathToId[location], location.GetDirectoryAndFileName()), nameof(item));\n        }\n\n        if (mapIdToPath.ContainsKey(item.Id))\n        {\n            throw new ArgumentException(\"An asset with the same id [{0}] is already registered with the location [{1}]\".ToFormat(item.Id, location.GetDirectoryAndFileName()), nameof(item));\n        }\n\n        if (location.HasDrive)\n        {\n            throw new ArgumentException(\"Asset location [{0}] cannot contain drive information\".ToFormat(location), nameof(item));\n        }\n\n        if (location.GetDirectory()?.StartsWith(\"..\", StringComparison.Ordinal) == true)\n        {\n            throw new ArgumentException(\"Asset location [{0}] cannot start with relative '..'\".ToFormat(location), nameof(item));\n        }\n\n        // Double check that this asset is not already stored in another package for this session","sourceCodeStart":337,"sourceCodeEnd":373,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/assets/Stride.Core.Assets/PackageAssetCollection.cs#L337-L373","documentation":"The collection maintains a mapPathToId index so each referenceable asset location is unique within a package. CheckCanAdd throws when the location being added is already registered to another asset id, preventing two referenceable assets from resolving to the same path.","triggerScenarios":"Adding an asset whose computed location (after optional namespace qualification) equals the location of an asset already in the collection, when the new asset is referenceable (AssetDescriptionAttribute.Referenceable defaults to true). Only applies when referenceable — non-referenceable assets may share locations.","commonSituations":"Duplicating an asset in code and reusing the same location string; importing assets that collide with existing file names; renaming scenarios where the old entry was not removed before adding the new one; two different source files mapping to the same package-relative location.","solutions":["Choose a unique location for the new asset (e.g. append a suffix) before adding.","Remove or rename the conflicting asset first: package.Assets.Remove(existing) or change its Location.","Retrieve the existing asset by location (package.Assets.Find(location)) if you actually meant to update it rather than add a duplicate.","Mark the asset type non-referenceable via AssetDescriptionAttribute if duplicate locations are legitimately acceptable for it."],"exampleFix":"// before\nvar item = new AssetItem(existingLocation, newAsset) { Id = AssetId.New() };\npackage.Assets.Add(item); // throws: location already registered\n\n// after\nif (package.Assets.Find(existingLocation) is { } existing)\n    package.Assets.Remove(existing);\npackage.Assets.Add(new AssetItem(existingLocation, newAsset) { Id = AssetId.New() });","handlingStrategy":"validation","validationCode":"if (package.Assets.Find(item.Location) is { } existing && referenceable)\n    package.Assets.Remove(existing);\npackage.Assets.Add(item);","typeGuard":"bool LocationIsFree(Package p, UFile loc) => p.Assets.Find(loc) == null;","tryCatchPattern":"try { package.Assets.Add(item); }\ncatch (ArgumentException e) when (e.Message.Contains(\"same location\"))\n{ /* find/replace or rename location */ }","preventionTips":["Check Find(location) before adding referenceable assets","Generate unique names for imported assets","Use Remove+Add for replacements rather than blind Add"],"tags":["assets","duplicate","location","argument-exception"],"backgroundTag":"file-already-exists","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}