{"record":{"id":"52f807db2512a209","repo":"ppy/osu","slug":"cannot-commit-a-rotate-operation-without-calling-b-52f807","errorCode":null,"errorMessage":"Cannot Commit a rotate operation without calling Begin first!","messagePattern":"Cannot Commit a rotate operation without calling Begin first!","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"osu.Game.Rulesets.Osu/Edit/OsuSelectionScaleHandler.cs","lineNumber":133,"sourceCode":"                scaleSlider(slider, scale, actualOrigin, objectsInScale[slider], axisRotation);\r\n            }\r\n            else\r\n            {\r\n                scale = ClampScaleToPlayfieldBounds(scale, actualOrigin, adjustAxis, axisRotation);\r\n\r\n                foreach (var (ho, originalState) in objectsInScale)\r\n                {\r\n                    ho.Position = GeometryUtils.GetScaledPosition(scale, actualOrigin, originalState.Position, axisRotation);\r\n                }\r\n            }\r\n\r\n            moveSelectionInBounds();\r\n        }\r\n\r\n        public override void Commit()\r\n        {\r\n            if (!OperationInProgress.Value)\r\n                throw new InvalidOperationException($\"Cannot {nameof(Commit)} a rotate operation without calling {nameof(Begin)} first!\");\r\n\r\n            changeHandler?.EndChange();\r\n\r\n            base.Commit();\r\n\r\n            objectsInScale = null;\r\n            OriginalSurroundingQuad = null;\r\n            defaultOrigin = null;\r\n        }\r\n\r\n        private IEnumerable<OsuHitObject> selectedMovableObjects => selectedItems.Cast<OsuHitObject>()\r\n                                                                                 .Where(h => h is not Spinner);\r\n\r\n        private Vector2 clampScaleToAdjustAxis(Vector2 scale, Axes adjustAxis)\r\n        {\r\n            switch (adjustAxis)\r\n            {\r\n                case Axes.Y:\r","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/ppy/osu/blob/d9c73e12adff2feaae4a3e158d36fe5883faf6ca/osu.Game.Rulesets.Osu/Edit/OsuSelectionScaleHandler.cs#L115-L151","documentation":"OsuSelectionScaleHandler.Commit() ends the change-handler transaction and nulls the scale state. Without a preceding Begin(), there is no open transaction to end. NOTE: The exception message says 'rotate operation' but the class is OsuSelectionScaleHandler — this is a copy-paste bug in the codebase; the message should say 'scale operation'. The underlying issue is the same lifecycle violation as the rotation handler.","triggerScenarios":"Calling Commit() when OperationInProgress.Value is false — e.g., a commit event firing without a prior Begin, or the operation was already committed.","commonSituations":"Double-commit from duplicate event handlers; lifecycle mismatch between the UI control and the scale handler. Developers may be confused by the misleading 'rotate' message and look in the wrong handler class.","solutions":["Ensure Begin() is called before Commit().","Guard Commit() behind an OperationInProgress.Value check.","When debugging this error, note the message incorrectly says 'rotate' — the actual class is OsuSelectionScaleHandler. The fix is in the scale handler, not the rotation handler."],"exampleFix":"// before\nscaleHandler.Commit(); // no prior Begin\n// (error message says 'rotate' but this is the scale handler — known copy-paste bug)\n\n// after\nif (scaleHandler.OperationInProgress.Value)\n    scaleHandler.Commit();","handlingStrategy":"validation","validationCode":"// Guard Commit against calls without a prior Begin\nif (scaleHandler.OperationInProgress.Value)\n    scaleHandler.Commit();","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pair Begin and Commit in a try-finally or using pattern to guarantee lifecycle correctness.","Guard Commit behind OperationInProgress.Value to make it idempotent.","Be aware that the error message says 'rotate' but the handler is OsuSelectionScaleHandler — this is a known copy-paste bug; do not look in the rotation handler when this fires."],"tags":["editor","osu-ruleset","selection","state-machine","scaling","known-bug"],"backgroundTag":null,"analyzedSha":"d9c73e12adff2feaae4a3e158d36fe5883faf6ca","analyzedAt":"2026-08-13T14:12:54.015Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}