{"record":{"id":"51c73d2bb0ca23de","repo":"stride3d/stride","slug":"no-resize-operation-in-progress","errorCode":null,"errorMessage":"No resize operation in progress.","messagePattern":"No resize operation in progress\\.","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/editor/Stride.Assets.Presentation/AssetEditors/SpriteEditor/ViewModels/ResizableSpriteInfoPartViewModel.cs","lineNumber":56,"sourceCode":"        {\n            var viewport = (ViewportViewModel)sender;\n            if (e.PropertyName == nameof(ViewportViewModel.ScaleFactor))\n                ScaleFactor = viewport.ScaleFactor;\n        }\n\n        void IResizingTarget.OnResizingStarted(ResizingDirection direction)\n        {\n            if (resizingTransaction != null || resizingContext != null)\n                throw new InvalidOperationException(\"A resize operation was already in progress.\");\n\n            resizingTransaction = UndoRedoService.CreateTransaction();\n            resizingContext = SynchronizationContext.Current;\n        }\n\n        void IResizingTarget.OnResizingDelta(ResizingDirection direction, double horizontalChange, double verticalChange)\n        {\n            if (resizingTransaction == null || resizingContext == null)\n                throw new InvalidOperationException(\"No resize operation in progress.\");\n\n            // The synchronization context has changed here, we must signal we intentionnally continue an existing transaction.\n            resizingTransaction.Continue();\n            OnResizeDelta(direction, horizontalChange, verticalChange);\n        }\n\n        void IResizingTarget.OnResizingCompleted(ResizingDirection direction, double horizontalChange, double verticalChange)\n        {\n            if (resizingTransaction == null || resizingContext == null)\n                throw new InvalidOperationException(\"No resize operation in progress.\");\n\n            // The synchronization context has changed here, we must signal we intentionnally continue an existing transaction.\n            resizingTransaction.Continue();\n            var transactionName = ComputeTransactionName(direction, horizontalChange, verticalChange);\n            UndoRedoService.SetName(resizingTransaction, transactionName);\n            resizingTransaction.Complete();\n\n            resizingTransaction = null;","sourceCodeStart":38,"sourceCodeEnd":74,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/editor/Stride.Assets.Presentation/AssetEditors/SpriteEditor/ViewModels/ResizableSpriteInfoPartViewModel.cs#L38-L74","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Ignore delta events when no resize is active: check resizingTransaction != null before applying.","Ensure OnResizingStarted always precedes delta events (start the transaction on gesture begin).","If the transaction was committed/cancelled externally, drop pending delta events instead of replaying them."],"exampleFix":"// before\nif (resizingTransaction == null || resizingContext == null)\n    throw new InvalidOperationException(\"No resize operation in progress.\");\n// after\nif (resizingTransaction == null || resizingContext == null)\n    return; // stale delta event, ignore silently","handlingStrategy":"try-catch","validationCode":"// only forward deltas between a matched start/end pair\nif (!gestureActive) return;\n((IResizingTarget)spriteVm).OnResizingDelta(direction, dx, dy);","typeGuard":"static bool ResizeActive(ResizableSpriteInfoPartViewModel vm) => vm.IsResizing;","tryCatchPattern":"try { ((IResizingTarget)spriteVm).OnResizingDelta(direction, dx, dy); }\ncatch (InvalidOperationException ex) when (ex.Message == \"No resize operation in progress.\") { gestureActive = false; /* stale event, drop it */ }","preventionTips":["Track gesture state at the input layer and drop deltas outside an active gesture.","Stop delta event delivery once OnResizingEnded runs.","Recreate the transaction (new gesture) after undo/redo invalidates the old one."],"tags":["invalid-state-transition","sprite-editor","lifecycle"],"backgroundTag":"invalid-state-transition","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"}