stride3d/stride · error · InvalidOperationException
No upgrader for asset type [{0}] allow to reach version {1}
Error message
No upgrader for asset type [{0}] allow to reach version {1} What it means
AssetUpgraderCollection.Validate walks the registered upgrader ranges from the earliest version, repeatedly advancing to the highest reachable Target, and verifies the chain terminates exactly at currentVersion. If the chain of upgraders for this asset type cannot reach the current version (a gap in the version graph), it throws InvalidOperationException reporting the asset type and the version that could not be reached.
Solutions
- Add (or restore) an upgrader covering the missing range so the chain reaches currentVersion.
- Fix start/target boundaries of existing upgraders so consecutive ranges connect without gaps.
- Ensure the assembly/attribute declaring the missing upgrader is actually registered/loaded.
- If the asset no longer supports old versions, remove the asset type or reject old assets instead of pretending a chain exists.
Example fix
// before (gap) RegisterUpgrader(typeof(U1), v(1,0,0,0), v(2,0,0,0)); RegisterUpgrader(typeof(U2), v(3,0,0,0), v(4,0,0,0)); // after RegisterUpgrader(typeof(U1), v(1,0,0,0), v(2,0,0,0)); RegisterUpgrader(typeof(U1b), v(2,0,0,0), v(3,0,0,0)); // closes the gap RegisterUpgrader(typeof(U2), v(3,0,0,0), v(4,0,0,0));
Defensive patterns
Strategy: validation
Validate before calling
// After registration, Validate() itself is the guard; call it at startup collection.Validate(); // throws early if the upgrade chain has gaps
Type guard
static bool ChainReachesCurrent(IEnumerable<VersionRange> ranges, PackageVersion current)
{
var v = ranges.Min(r => r.Start);
foreach (var r in ranges.OrderBy(r => r.Start))
if (r.Contains(v)) v = r.Target;
return v == current;
} Try / catch
try
{
collection.Validate();
}
catch (InvalidOperationException ex)
{
logger.Error($"Upgrade chain incomplete: {ex.Message}. Register the missing upgrader range.");
} Prevention
- Never delete an upgrader for an old version while older assets may still exist.
- Run Validate() in unit tests for every asset type's upgrader collection.
- Keep each upgrader's start equal to the previous upgrader's target.
When it happens
Trigger: Loading/validating a package whose asset type has upgraders registered with a gap, e.g. ranges (1.0→2.0) and (3.0→4.0) with nothing covering 2.0→3.0, so the iteration stops before currentVersion and version != currentVersion.
Common situations: Removing an upgrader for an intermediate asset version that older assets still need; a broken upgrade chain after version bumps where consecutive upgraders' ranges don't abut; plugin/assembly providing an upgrader for the missing range not loaded.
Understand the failure class
Background: "not installed", "pip install", "required for": how missing-dependency errors surface across open-source libraries — this error's family across 34 libraries.
Related errors
- The target version is lower or equal to the start version.
- The upgrader has a target version higher that the current ve
- The upgrader overlaps with another upgrader.
- No upgrader found for version {0} of asset type [{1}]
- Invalid version format [{version}]
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/924cd0e049a41b08.
Report an issue: GitHub.
Appendix: source
Thrown at sources/assets/Stride.Core.Assets/AssetUpgraderCollection.cs:82
}
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)
break;
}
if (version != currentVersion)
throw new InvalidOperationException("No upgrader for asset type [{0}] allow to reach version {1}".ToFormat(AssetType.Name, currentVersion));
}
}
public IAssetUpgrader GetUpgrader(PackageVersion initialVersion, out PackageVersion targetVersion)
{
lock (upgraders)
{
var upgrader = upgraders.FirstOrDefault(x => x.Key.Contains(initialVersion));
if (upgrader.Value == null)
throw new InvalidOperationException("No upgrader found for version {0} of asset type [{1}]".ToFormat(currentVersion, AssetType.Name));
targetVersion = upgrader.Key.Target;
if (!instances.TryGetValue(upgrader.Value, out var result))
{
// Cache the upgrader instances
result = (IAssetUpgrader)Activator.CreateInstance(upgrader.Value)!;
instances.Add(upgrader.Value, result);
}View on GitHub (pinned to 96fad776d2)