stride3d/stride · error · InvalidOperationException

No resize operation in progress.

Error message

No resize operation in progress.

What it means

ResizableSpriteInfoPartViewModel.OnResizingDelta applies incremental resize changes inside an active undo transaction. It throws InvalidOperationException when no resize is in progress (resizingTransaction or resizingContext is null), because Continue() and the delta application require an open transaction.

Solutions

  1. Ignore delta events when no resize is active: check resizingTransaction != null before applying.
  2. Ensure OnResizingStarted always precedes delta events (start the transaction on gesture begin).
  3. If the transaction was committed/cancelled externally, drop pending delta events instead of replaying them.

Example fix

// before
if (resizingTransaction == null || resizingContext == null)
    throw new InvalidOperationException("No resize operation in progress.");
// after
if (resizingTransaction == null || resizingContext == null)
    return; // stale delta event, ignore silently
Defensive patterns

Strategy: try-catch

Validate before calling

// only forward deltas between a matched start/end pair
if (!gestureActive) return;
((IResizingTarget)spriteVm).OnResizingDelta(direction, dx, dy);

Type guard

static bool ResizeActive(ResizableSpriteInfoPartViewModel vm) => vm.IsResizing;

Try / catch

try { ((IResizingTarget)spriteVm).OnResizingDelta(direction, dx, dy); }
catch (InvalidOperationException ex) when (ex.Message == "No resize operation in progress.") { gestureActive = false; /* stale event, drop it */ }

Prevention

When it happens

Trigger: OnResizingDelta called without a preceding successful OnResizingStarted, or after OnResizingEnded already cleared resizingTransaction/resizingContext — e.g. delta events arriving late or after pointer capture was lost.

Common situations: Stale mouse-move events delivered after resize end; resize delta handlers wired without the start handler; editor state reset (undo/redo) mid-gesture clearing the transaction.

Understand the failure class

Background: "Invalid state transition" errors: "status must be X, actually Y", "already rejected/charging/uninstalled", "cannot ... while running" — what they mean when a library rejects your call — this error's family across 31 libraries.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/51c73d2bb0ca23de. Report an issue: GitHub.

Appendix: source

Thrown at sources/editor/Stride.Assets.Presentation/AssetEditors/SpriteEditor/ViewModels/ResizableSpriteInfoPartViewModel.cs:56

        {
            var viewport = (ViewportViewModel)sender;
            if (e.PropertyName == nameof(ViewportViewModel.ScaleFactor))
                ScaleFactor = viewport.ScaleFactor;
        }

        void IResizingTarget.OnResizingStarted(ResizingDirection direction)
        {
            if (resizingTransaction != null || resizingContext != null)
                throw new InvalidOperationException("A resize operation was already in progress.");

            resizingTransaction = UndoRedoService.CreateTransaction();
            resizingContext = SynchronizationContext.Current;
        }

        void IResizingTarget.OnResizingDelta(ResizingDirection direction, double horizontalChange, double verticalChange)
        {
            if (resizingTransaction == null || resizingContext == null)
                throw new InvalidOperationException("No resize operation in progress.");

            // The synchronization context has changed here, we must signal we intentionnally continue an existing transaction.
            resizingTransaction.Continue();
            OnResizeDelta(direction, horizontalChange, verticalChange);
        }

        void IResizingTarget.OnResizingCompleted(ResizingDirection direction, double horizontalChange, double verticalChange)
        {
            if (resizingTransaction == null || resizingContext == null)
                throw new InvalidOperationException("No resize operation in progress.");

            // The synchronization context has changed here, we must signal we intentionnally continue an existing transaction.
            resizingTransaction.Continue();
            var transactionName = ComputeTransactionName(direction, horizontalChange, verticalChange);
            UndoRedoService.SetName(resizingTransaction, transactionName);
            resizingTransaction.Complete();

            resizingTransaction = null;

View on GitHub (pinned to 96fad776d2)