ppy/osu · error · InvalidOperationException
Cannot Commit a rotate operation without calling Begin first
Error message
Cannot Commit a rotate operation without calling Begin first!
What it means
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.
Source
Thrown at osu.Game.Rulesets.Osu/Edit/OsuSelectionScaleHandler.cs:133
scaleSlider(slider, scale, actualOrigin, objectsInScale[slider], axisRotation);
}
else
{
scale = ClampScaleToPlayfieldBounds(scale, actualOrigin, adjustAxis, axisRotation);
foreach (var (ho, originalState) in objectsInScale)
{
ho.Position = GeometryUtils.GetScaledPosition(scale, actualOrigin, originalState.Position, axisRotation);
}
}
moveSelectionInBounds();
}
public override void Commit()
{
if (!OperationInProgress.Value)
throw new InvalidOperationException($"Cannot {nameof(Commit)} a rotate operation without calling {nameof(Begin)} first!");
changeHandler?.EndChange();
base.Commit();
objectsInScale = null;
OriginalSurroundingQuad = null;
defaultOrigin = null;
}
private IEnumerable<OsuHitObject> selectedMovableObjects => selectedItems.Cast<OsuHitObject>()
.Where(h => h is not Spinner);
private Vector2 clampScaleToAdjustAxis(Vector2 scale, Axes adjustAxis)
{
switch (adjustAxis)
{
case Axes.Y:
View on GitHub (pinned to d9c73e12ad)
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.
Example fix
// before
scaleHandler.Commit(); // no prior Begin
// (error message says 'rotate' but this is the scale handler — known copy-paste bug)
// after
if (scaleHandler.OperationInProgress.Value)
scaleHandler.Commit(); Defensive patterns
Strategy: validation
Validate before calling
// Guard Commit against calls without a prior Begin
if (scaleHandler.OperationInProgress.Value)
scaleHandler.Commit(); Prevention
- 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.
When it happens
Trigger: Calling Commit() when OperationInProgress.Value is false — e.g., a commit event firing without a prior Begin, or the operation was already committed.
Common situations: 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.
Related errors
- Cannot Begin a scale operation while another is in progress!
- Cannot Update a scale operation without calling Begin first!
- Cannot Begin a rotate operation while another is in progress
- Cannot Update a rotate operation without calling Begin first
- Cannot Commit a rotate operation without calling Begin first
AI-assisted analysis of ppy/osu@d9c73e12ad (2026-08-13).
Data as JSON: /api/errors/52f807db2512a209.
Report an issue: GitHub.