stride3d/stride · error · TransactionException
A disposed operation cannot be rollforwarded.
Error message
A disposed operation cannot be rollforwarded.
What it means
Lifecycle guard in Operation.Rollforward: the operation is frozen (IsFrozen), meaning it was completed and its saved state was discarded; a frozen/disposed operation can no longer be rolled forward. Redoing an operation after the transaction was finalized is not allowed.
Solutions
- Only call Rollforward on live (non-frozen) operations; check IsFrozen first
- Create a new transaction/operation to re-apply committed changes
- Rebuild the redo stack from a fresh source after completion
Example fix
// before
transaction.Complete();
operation.Rollforward(); // throws
// after
if (!operation.IsFrozen)
operation.Rollforward(); Defensive patterns
Strategy: type-guard
Validate before calling
if (operation.IsFrozen)
throw new InvalidOperationException("Cannot roll forward a completed operation"); Type guard
bool CanRollforward(IOperation op) => op is Operation o && !o.IsFrozen;
Try / catch
try { operation.Rollforward(); }
catch (TransactionException ex) when (ex.Message.Contains("disposed operation cannot be rollforwarded"))
{
logger.LogWarning("Attempted rollforward of completed operation");
} Prevention
- Only redo live operations; rebuild redo entries after completion
- Check IsFrozen before Rollforward
- Create a new transaction to re-apply committed changes
When it happens
Trigger: Calling IOperation.Rollforward() on an operation after its transaction was completed/disposed (IsFrozen == true), e.g. a redo stack holding references to operations from finished transactions.
Common situations: Redo after commit without creating a new transaction, replaying stored operations that were already frozen.
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
- This operation is already frozen.
- A disposed operation cannot be rollbacked.
- Could not find asset
- Expect name1=value1;name2=value2 format.
- assetItem must be an absolute path
AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14).
Data as JSON: /api/errors/4b6453962795aca0.
Report an issue: GitHub.
Appendix: source
Thrown at sources/core/Stride.Core.Design/Transactions/Operation.cs:95
/// <inheritdoc/>
void IOperation.Rollback()
{
if (IsFrozen)
throw new TransactionException("A disposed operation cannot be rollbacked.");
if (inProgress)
throw new TransactionException("This operation is already in progress");
inProgress = true;
Rollback();
inProgress = false;
}
/// <inheritdoc/>
void IOperation.Rollforward()
{
if (IsFrozen)
throw new TransactionException("A disposed operation cannot be rollforwarded.");
if (inProgress)
throw new TransactionException("This operation is already in progress");
inProgress = true;
Rollforward();
inProgress = false;
}
}
View on GitHub (pinned to 96fad776d2)