{"record":{"id":"8ccfffdf6aee737c","repo":"stride3d/stride","slug":"asset-of-type-assettype-was-migrated-but-still-its-new","errorCode":null,"errorMessage":"Asset of type {assetType} was migrated, but still its new version {newSerializedVersion} doesn't match expected version {expectedVersion}.","messagePattern":"Asset of type (.+?) was migrated, but still its new version (.+?) doesn't match expected version (.+?)\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/assets/Stride.Core.Assets/AssetMigration.cs","lineNumber":160,"sourceCode":"                // Stop if the next version would be higher than what is expected\n                if (untilVersion != null && targetVersion > untilVersion)\n                    break;\n\n                upgrader.Upgrade(context, dependencyName, currentVersion, targetVersion, yamlRootNode, loadAsset);\n                currentVersion = targetVersion;\n            }\n\n            // Make sure asset is updated to latest version\n            PackageVersion? newSerializedVersion = null;\n            if (yamlRootNode.Children.TryGetValue(new YamlScalarNode(nameof(Asset.SerializedVersion)), out var serializedVersionNode))\n            {\n                var newSerializedVersionForDefaultPackage = ((YamlMappingNode)serializedVersionNode).Children[new YamlScalarNode(dependencyName)];\n                newSerializedVersion = PackageVersion.Parse(((YamlScalarNode)newSerializedVersionForDefaultPackage).Value);\n            }\n\n            if (untilVersion == null && newSerializedVersion != expectedVersion)\n            {\n                throw new InvalidOperationException($\"Asset of type {assetType} was migrated, but still its new version {newSerializedVersion} doesn't match expected version {expectedVersion}.\");\n            }\n\n            context.Log.Verbose($\"{Path.GetFullPath(assetFullPath)} updated from version {serializedVersion} to version {expectedVersion}\");\n\n            return true;\n        }\n\n        return false;\n    }\n}\n","sourceCodeStart":142,"sourceCodeEnd":171,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/assets/Stride.Core.Assets/AssetMigration.cs#L142-L171","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"// before: upgrader edits content but never updates the version node\n// after\npublic class MyAssetUpgrader : AssetUpgraderBase\n{\n    protected override void UpgradeAsset(AssetMigrationContext context, PackageVersion currentVersion, PackageVersion targetVersion, YamlMappingNode assetNode)\n    {\n        // ... content upgrades ...\n        UpdateAssetVersion(assetNode, targetVersion);\n    }\n}","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"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}\"); }","preventionTips":["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."],"tags":["assets","migration","invariant"],"backgroundTag":"internal-invariant-violation","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-15T23:17:13.987Z"}