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
- Fix the upgrader implementation so it writes the correct target version node to the YAML asset.
- Verify upgrader StartVersion/TargetVersion ranges chain exactly from serializedVersion to expectedVersion.
- 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
- Use AssetUpgraderBase.UpdateAssetVersion in every custom upgrader.
- Unit-test each upgrader asserts the output version equals TargetVersion.
- Keep TargetVersion ranges consistent with the attribute-declared target.
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
- Asset of type has been serialized with newer version , but…
- Asset of type should be updated from version to , but no…
- Unable to find the base
- Unable to find the graph corresponding to the base part
- The base is unset for the current node.
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)