stride3d/stride · error · InvalidOperationException

Asset of type was migrated, but still its new version…

Error message

Asset of type {assetType} was migrated, but still its new version {newSerializedVersion} doesn't match expected version {expectedVersion}.

What it means

Thrown by AssetMigration.MigrateAssetIfNeeded after running the registered upgraders: the migration loop completed, but the asset's rewritten serialized version still does not equal expectedVersion. This indicates an internal invariant failure — an upgrader did not advance (or advanced past) the version node as required.

Solutions

  1. Fix the upgrader implementation so it writes the correct target version node to the YAML asset.
  2. Verify upgrader StartVersion/TargetVersion ranges chain exactly from serializedVersion to expectedVersion.
  3. Inspect the migrated asset file to see which version the last upgrader actually wrote.

Example fix

// before: upgrader edits content but never updates the version node
// after
public class MyAssetUpgrader : AssetUpgraderBase
{
    protected override void UpgradeAsset(AssetMigrationContext context, PackageVersion currentVersion, PackageVersion targetVersion, YamlMappingNode assetNode)
    {
        // ... content upgrades ...
        UpdateAssetVersion(assetNode, targetVersion);
    }
}
Defensive patterns

Strategy: try-catch

Try / catch

try { AssetMigration.MigrateAssetIfNeeded(...); } catch (InvalidOperationException ex) when (ex.Message.Contains("still its new version")) { log.Error($"Upgrader bug: final version mismatch for {assetType}: {ex.Message}"); }

Prevention

When it happens

Trigger: Running MigrateAssetIfNeeded with no explicit untilVersion; after executing the upgrader chain the dependency version node in the YAML asset reads a value different from expectedVersion.

Common situations: A custom IAssetUpgrader forgets to update the version node in the YAML; a buggy upgrader writes a wrong target version; upgrader registration ranges overlap or skip versions.

Understand the failure class

Background: "This is a bug, please report it": internal invariant violations, unreachable panics, and SNH errors explained — this error's family across 47 libraries.

Related errors


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

Appendix: source

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

                // 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;
            if (yamlRootNode.Children.TryGetValue(new YamlScalarNode(nameof(Asset.SerializedVersion)), out var serializedVersionNode))
            {
                var newSerializedVersionForDefaultPackage = ((YamlMappingNode)serializedVersionNode).Children[new YamlScalarNode(dependencyName)];
                newSerializedVersion = PackageVersion.Parse(((YamlScalarNode)newSerializedVersionForDefaultPackage).Value);
            }

            if (untilVersion == null && newSerializedVersion != expectedVersion)
            {
                throw new InvalidOperationException($"Asset of type {assetType} was migrated, but still its new version {newSerializedVersion} doesn't match expected version {expectedVersion}.");
            }

            context.Log.Verbose($"{Path.GetFullPath(assetFullPath)} updated from version {serializedVersion} to version {expectedVersion}");

            return true;
        }

        return false;
    }
}

View on GitHub (pinned to 96fad776d2)