stride3d/stride · error · ArgumentException
The upgrader overlaps with another upgrader.
Error message
The upgrader overlaps with another upgrader.
What it means
RegisterUpgrader builds a VersionRange(startVersion, targetVersion) and checks whether any already-registered upgrader's range overlaps it. Because the collection resolves an initial version to exactly one upgrader via FirstOrDefault, ranges must be disjoint; an overlap would make upgrader selection ambiguous, so an ArgumentException is thrown.
Solutions
- Adjust the new upgrader's start/target versions so its range does not intersect any existing range.
- Remove or correct the conflicting registered upgrader whose range overlaps.
- Enumerate existing upgraders (or log upgraders keys) to find which VersionRange collides.
- If the same upgrader was registered twice, remove the duplicate attribute/registration call.
Example fix
// before RegisterUpgrader(typeof(UpgraderA), v(4,0,0,0), v(4,1,0,0)); RegisterUpgrader(typeof(UpgraderB), v(4,0,5,0), v(4,2,0,0)); // overlaps UpgraderA // after RegisterUpgrader(typeof(UpgraderA), v(4,0,0,0), v(4,1,0,0)); RegisterUpgrader(typeof(UpgraderB), v(4,1,0,0), v(4,2,0,0)); // contiguous, disjoint
Defensive patterns
Strategy: validation
Validate before calling
var range = new VersionRange(start, target);
bool overlaps = registeredRanges.Any(r => r.Overlap(range));
if (overlaps) throw new InvalidOperationException("New upgrader range overlaps an existing one"); Type guard
static bool IsDisjoint(VersionRange candidate, IEnumerable<VersionRange> existing) => !existing.Any(r => r.Overlap(candidate));
Try / catch
try
{
collection.RegisterUpgrader(typeof(MyUpgrader), start, target);
}
catch (ArgumentException)
{
// inspect existing ranges and adjust start/target to be disjoint
} Prevention
- Keep consecutive upgrader ranges contiguous: next range starts where the previous target ends.
- Before adding an upgrader, list all existing ranges for the asset type.
- Avoid duplicating upgrader attributes on classes; one registration per range.
When it happens
Trigger: Calling RegisterUpgrader twice with ranges that share any version, e.g. (4.0.0.0→4.1.0.0) then (4.0.5.0→4.2.0.0); or two AssetUpgraderAttributes declaring ranges whose [start, target] intervals intersect for the same asset type.
Common situations: Adding a new upgrader without checking existing ones covering part of the same span; off-by-one boundaries in start/target versions of consecutive upgraders; accidentally registering the same upgrader type twice (e.g. attribute duplicated on a class or assembly scanned twice).
Understand the failure class
Background: Conflicting config options: "cannot be used together" — configuration validation errors across open-source libraries — this error's family across 162 libraries.
Related errors
- The target version is lower or equal to the start version.
- The upgrader has a target version higher that the current…
- No upgrader for asset type
- No upgrader found for version
- Asset of type has been serialized with newer version , but…
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/8d9b44edf5220ee4.
Report an issue: GitHub.
Appendix: source
Thrown at sources/assets/Stride.Core.Assets/AssetUpgraderCollection.cs:59
this.currentVersion = currentVersion;
AssetRegistry.IsAssetOrPackageType(assetType, true);
AssetType = assetType;
}
public Type AssetType { get; }
internal void RegisterUpgrader(Type upgraderType, PackageVersion startVersion, PackageVersion targetVersion)
{
lock (upgraders)
{
if (targetVersion > currentVersion)
throw new ArgumentException("The upgrader has a target version higher that the current version.");
var range = new VersionRange(startVersion, targetVersion);
if (upgraders.Any(x => x.Key.Overlap(range)))
{
throw new ArgumentException("The upgrader overlaps with another upgrader.");
}
upgraders.Add(new VersionRange(startVersion, targetVersion), upgraderType);
}
}
internal void Validate(PackageVersion minVersion)
{
lock (upgraders)
{
var version = minVersion;
foreach (var upgrader in upgraders)
{
if (!upgrader.Key.Contains(version))
continue;
version = upgrader.Key.Target;
if (version == currentVersion)View on GitHub (pinned to 96fad776d2)