stride3d/stride · error · InvalidOperationException

A resize operation was already in progress.

Error message

A resize operation was already in progress.

What it means

ResizableSpriteInfoPartViewModel.OnResizingStarted begins a sprite resize transaction by creating an undo transaction and capturing the synchronization context. It throws InvalidOperationException if a resize transaction or context is already active, enforcing one resize at a time.

Solutions

  1. Ensure OnResizingEnded is always called (even on cancel/lost focus) so the previous transaction and context are cleared.
  2. Cancel/complete the in-progress transaction before starting a new resize.
  3. Guard input handling so a new resize gesture cannot begin while one is active (ignore or abort the second).

Example fix

// before
if (resizingTransaction != null || resizingContext != null)
    throw new InvalidOperationException("A resize operation was already in progress.");
// after
if (resizingTransaction != null)
{
    UndoRedoService.CancelTransaction(); // or commit it
    resizingTransaction = null;
    resizingContext = null;
}
resizingTransaction = UndoRedoService.CreateTransaction();
resizingContext = SynchronizationContext.Current;
Defensive patterns

Strategy: try-catch

Validate before calling

// ensure no gesture is active before starting a new one
if (spriteVm.ResizingInProgress) return; // expose or track this flag at the call site

Type guard

static bool CanStartResize(ResizableSpriteInfoPartViewModel vm) => !vm.IsResizing; // wrap the private transaction/context state

Try / catch

try { ((IResizingTarget)spriteVm).OnResizingStarted(direction); }
catch (InvalidOperationException ex) when (ex.Message == "A resize operation was already in progress.") { AbortCurrentGesture(); }

Prevention

When it happens

Trigger: OnResizingStarted invoked while resizingTransaction != null or resizingContext != null — e.g. a second resizing gesture started without the previous one finishing (missing OnResizingEnded), or concurrent pointer/capture events.

Common situations: Mouse capture glitches in the sprite editor where the end-resize event is lost; overlapping resize gestures from different input sources; UI re-entrancy during an in-flight 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/34252341bdd4f5d6. Report an issue: GitHub.

Appendix: source

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

            Sprite.Editor.Viewport.PropertyChanged -= ViewportPropertyChanged;
            base.Destroy();
        }

        protected abstract void OnResizeDelta(ResizingDirection direction, double horizontalChange, double verticalChange);

        protected abstract string ComputeTransactionName(ResizingDirection direction, double horizontalChange, double verticalChange);

        private void ViewportPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            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)

View on GitHub (pinned to 96fad776d2)