{"record":{"id":"c867fc07d4a81584","repo":"stride3d/stride","slug":"unable-to-create-a-transaction-a-rollback-or-rollforward","errorCode":null,"errorMessage":"Unable to create a transaction. A rollback or rollforward operation is in progress.","messagePattern":"Unable to create a transaction\\. A rollback or rollforward operation is in progress\\.","errorType":"exception","errorClass":"TransactionException","httpStatus":null,"severity":"error","filePath":"sources/core/Stride.Core.Design/Transactions/TransactionStack.cs","lineNumber":77,"sourceCode":"    /// <inheritdoc/>\n    public event EventHandler<TransactionEventArgs>? TransactionRollbacked;\n\n    /// <inheritdoc/>\n    public event EventHandler<TransactionEventArgs>? TransactionRollforwarded;\n\n    /// <inheritdoc/>\n    public event EventHandler<TransactionsDiscardedEventArgs>? TransactionDiscarded;\n\n    /// <inheritdoc/>\n    public event EventHandler<EventArgs>? Cleared;\n\n    /// <inheritdoc/>\n    public ITransaction CreateTransaction(TransactionFlags flags = TransactionFlags.None)\n    {\n        lock (lockObject)\n        {\n            if (RollInProgress)\n                throw new TransactionException(\"Unable to create a transaction. A rollback or rollforward operation is in progress.\");\n\n            var transaction = new Transaction(this, flags);\n            if ((flags & TransactionFlags.KeepParentsAlive) != 0)\n            {\n                foreach (var parentTransaction in transactionsInProgress)\n                    parentTransaction.AddReference();\n            }\n\n            transactionsInProgress.Push(transaction);\n            TransactionInProgress = true;\n            return transaction;\n        }\n    }\n\n    /// <inheritdoc/>\n    public void PushOperation(Operation operation)\n    {\n        lock (lockObject)","sourceCodeStart":59,"sourceCodeEnd":95,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/core/Stride.Core.Design/Transactions/TransactionStack.cs#L59-L95","documentation":"Thrown by TransactionStack.CreateTransaction when the stack is currently executing a rollback or rollforward. New transactions cannot be created while the undo/redo machinery is unwinding/applying operations, as that would corrupt the stack.","triggerScenarios":"Calling CreateTransaction from another thread (or re-entrantly from a rollback/rollforward handler) while TransactionStack.RollInProgress is true — e.g. transactions spawned from events fired during an undo/redo.","commonSituations":"UI event handlers firing during an undo operation, background tasks creating transactions concurrently with a rollback, re-entrant edits inside transaction completion events.","solutions":["Defer transaction creation until the rollback/rollforward finishes (check RollInProgress first and retry)","Do not create transactions from handlers invoked during undo/redo; queue the work and apply it afterward","Synchronize transaction creation through a single dispatcher/thread"],"exampleFix":"// before\nstack.Rollback(); // triggers events\nvar t = stack.CreateTransaction(); // throws from event handler\n// after\nITransaction t = null;\nif (!stack.RollInProgress)\n    t = stack.CreateTransaction();\nelse\n    pendingWork.Enqueue(() => stack.CreateTransaction());","handlingStrategy":"validation","validationCode":"if (stack.RollInProgress)\n    throw new InvalidOperationException(\"Stack is rolling; defer transaction creation\");\nvar t = stack.CreateTransaction();","typeGuard":"bool CanCreateTransaction(TransactionStack s) => !s.RollInProgress;","tryCatchPattern":"try { return stack.CreateTransaction(); }\ncatch (TransactionException ex) when (ex.Message.Contains(\"rollback or rollforward operation is in progress\"))\n{\n    pendingTransactions.Enqueue(flags);\n    return null;\n}","preventionTips":["Check RollInProgress before creating transactions","Never create transactions from undo/redo event handlers","Marshal transaction creation through one thread/dispatcher and queue during rolls"],"tags":["transaction","undo-redo","concurrency"],"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-16T04:17:20.429Z"}