{"record":{"id":"ef3c685811589347","repo":"stride3d/stride","slug":"code-upgrade-gated-at-registration-gateversion-declares","errorCode":null,"errorMessage":"Code upgrade gated at {registration.GateVersion} declares resolveSince {resolveSince}, above the project's from-version {item.FromVersion}. Intermediate version-overridden restores (chained boundaries) are not implemented yet; only single-step resolution at the from-version is supported.","messagePattern":"Code upgrade gated at (.+?) declares resolveSince (.+?), above the project's from-version (.+?)\\. Intermediate version-overridden restores \\(chained boundaries\\) are not implemented yet; only single-step resolution at the from-version is supported\\.","errorType":"exception","errorClass":"NotImplementedException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Assets/CodeUpgrade/RoslynCodeUpgradeRunner.cs","lineNumber":53,"sourceCode":"\n            var registry = new UpgradeRegistry();\n            provider.DeclareUpgrades(registry);\n\n            var applicable = new List<CodeUpgrade>();\n            foreach (var registration in registry.CodeUpgrades)\n            {\n                // Gate: the change landed at GateVersion, so migrate any project coming from below it.\n                if (item.FromVersion.Version >= registration.GateVersion.Version)\n                    continue;\n\n                // resolveSince is the exact version where the matched OLD form first exists. When it's above\n                // the from-version the rule can't bind against the from-version closure; resolving it would\n                // need a version-overridden intermediate restore of the package family at that version\n                // (sequenced low→high, merging overlapping resolution windows, replaying any family package\n                // rename up to it), then a fresh workspace opened there. Not implemented — fail loud rather\n                // than silently resolve at the from-version, which would no-op the rule.\n                if (registration.ResolveSince is { } resolveSince && resolveSince.Version > item.FromVersion.Version)\n                    throw new NotImplementedException(\n                        $\"Code upgrade gated at {registration.GateVersion} declares resolveSince {resolveSince}, above the \" +\n                        $\"project's from-version {item.FromVersion}. Intermediate version-overridden restores (chained \" +\n                        $\"boundaries) are not implemented yet; only single-step resolution at the from-version is supported.\");\n\n                applicable.AddRange(registration.Upgrades);\n            }\n            if (applicable.Count > 0)\n                plans.Add((item, applicable));\n        }\n        if (plans.Count == 0)\n        {\n            log.Info($\"Code upgrade: {pending.Count} pending project(s), no applicable source migrations.\");\n            return;\n        }\n\n        log.Info($\"Code upgrade: applying source migrations to {plans.Count} project(s)...\");\n\n        try","sourceCodeStart":35,"sourceCodeEnd":71,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Assets/CodeUpgrade/RoslynCodeUpgradeRunner.cs#L35-L71","documentation":"The Roslyn code-upgrade runner only supports single-step resolution at the project's from-version. If a gated upgrade declares ResolveSince above that from-version, resolving it would require an unimplemented intermediate version-overridden restore, so the runner fails loudly with NotImplementedException instead of silently no-oping the rule.","triggerScenarios":"Run iterates upgrade registrations; a registration has ResolveSince set to a version strictly greater than item.FromVersion.","commonSituations":"Running a code upgrade on a project whose from-version is older than the resolver-supported boundary, chained package-family upgrades across multiple version boundaries, upgrading a project pinned to an intermediate old package version.","solutions":["Raise the project's from-version (upgrade stepwise) so it is >= the rule's ResolveSince version","Split the upgrade into multiple sequential runs, each within a supported version boundary","Remove or adjust the ResolveSince on the custom upgrade registration if you own the rule","Implement/file support for chained intermediate restores if this scenario must be supported"],"exampleFix":null,"handlingStrategy":"validation","validationCode":"// before running the upgrade, check gate versions against the project's from-version\nforeach (var reg in registrations)\n    if (reg.ResolveSince is { } rs && rs.Version > item.FromVersion.Version)\n        throw new InvalidOperationException($\"Rule {reg.GateVersion} needs ResolveSince handling; raise from-version or drop ResolveSince.\");","typeGuard":"static bool IsSingleStepSupported(UpgradeRegistration reg, UpgradeItem item) =>\n    !(reg.ResolveSince is { } rs && rs.Version > item.FromVersion.Version);","tryCatchPattern":"try\n{\n    await runner.Run(upgradeItems);\n}\ncatch (NotImplementedException ex) when (ex.Message.Contains(\"resolveSince\"))\n{\n    logger.Error(\"Chained boundary upgrade unsupported; adjust from-version or rule: \" + ex.Message);\n}","preventionTips":["Keep project from-versions at or above the ResolveSince of all applied rules","Upgrade projects in single supported version steps, not across multiple boundaries","Document ResolveSince constraints for custom upgrade rules","Test code upgrades on a branch before running on the main project"],"tags":["code-upgrade","roslyn","unsupported-feature"],"backgroundTag":"method-not-implemented","analyzedSha":"96fad776d210c221682aac1ccdf4c79dc046fc38","analyzedAt":"2026-09-14T02:59:31.279Z","contentChangedAt":"2026-09-14T02:59:31.279Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}