stride3d/stride · error · InvalidOperationException

Asset of type should be updated from version to , but no…

Error message

Asset of type {assetType} should be updated from version {serializedVersion} to {expectedVersion}, but no asset migration path was found

What it means

Thrown by AssetMigration.MigrateAssetIfNeeded when an asset's serialized version is older than the current expected version, but AssetRegistry.GetAssetUpgraders returns no registered upgrader chain for the asset type. The library refuses to load the asset because it cannot bring the serialized data up to the format the code expects. This is a registration/versioning gap, not data corruption.

Solutions

  1. Register an asset upgrader for the type covering the missing version range (AssetUpgraderAttribute or AssetRegistry registration).
  2. If migration is not intended, update the asset file to the current version manually or recreate it.
  3. Ensure the assembly containing the upgrader is referenced and loaded so GetAssetUpgraders finds it.

Example fix

// before: asset still at version 0.1.0, no upgrader
// after
[AssetUpgrader("MyGame", "MyAsset", "0.1.0", "0.2.0", typeof(MyAssetUpgrader))]
public class MyAsset { ... }
Defensive patterns

Strategy: try-catch

Validate before calling

if (AssetRegistry.GetAssetUpgraders(assetType, dependencyName) == null)
    throw new InvalidOperationException($"No upgrader registered for {assetType} from {serializedVersion} to {expectedVersion}");

Try / catch

try { AssetMigration.MigrateAssetIfNeeded(...); } catch (InvalidOperationException ex) when (ex.Message.Contains("no asset migration path")) { log.Error($"Cannot load asset {assetFullPath}: missing upgrader. {ex.Message}"); }

Prevention

When it happens

Trigger: Loading (migrating) an asset whose stored version is behind expectedVersion while no AssetUpgraderAttribute/upgrader is registered for that assetType from serializedVersion to expectedVersion (GetAssetUpgraders returns null).

Common situations: An asset file was created with an older Stride/plugin version; a custom asset type changed its version but the author forgot to register an upgrader; an assembly defining upgraders is not loaded in the running process.

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


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

Appendix: source

Thrown at sources/assets/Stride.Core.Assets/AssetMigration.cs:133

        }

        if (serializedVersion > expectedVersion)
        {
            // Try to open an asset newer than what we support (probably generated by a newer Stride)
            throw new InvalidOperationException($"Asset of type {assetType} has been serialized with newer version {serializedVersion}, but only version {expectedVersion} is supported. Was this asset created with a newer version of Stride?");
        }

        if (serializedVersion < expectedVersion)
        {
            // Perform asset upgrade
            context.Log.Verbose($"{Path.GetFullPath(assetFullPath)} needs update, from version {serializedVersion} to version {expectedVersion}");

            using var yamlAsset = loadAsset.AsYamlAsset();
            var yamlRootNode = yamlAsset.RootNode;

            // Check if there is any asset updater
            var assetUpgraders = AssetRegistry.GetAssetUpgraders(assetType, dependencyName)
                ?? throw new InvalidOperationException($"Asset of type {assetType} should be updated from version {serializedVersion} to {expectedVersion}, but no asset migration path was found");

            // Instantiate asset updaters
            var currentVersion = serializedVersion;
            while (currentVersion != expectedVersion)
            {
                // This will throw an exception if no upgrader is available for the given version, exiting the loop in case of error.
                var upgrader = assetUpgraders.GetUpgrader(currentVersion, out var targetVersion);

                // Stop if the next version would be higher than what is expected
                if (untilVersion != null && targetVersion > untilVersion)
                    break;

                upgrader.Upgrade(context, dependencyName, currentVersion, targetVersion, yamlRootNode, loadAsset);
                currentVersion = targetVersion;
            }

            // Make sure asset is updated to latest version
            PackageVersion? newSerializedVersion = null;

View on GitHub (pinned to 96fad776d2)