stride3d/stride · error · TransactionException

There is not transaction in progress in the transaction…

Error message

There is not transaction in progress in the transaction stack.

What it means

EndTransaction requires at least one transaction to be in progress; the transactionsInProgress stack must be non-empty so the passed transaction can be matched and popped. This error (note the typo 'not transaction' in the message) is thrown when EndTransaction is called with no transaction currently in progress.

Solutions

  1. Ensure every EndTransaction call is paired with exactly one successful CreateTransaction/PushTransaction.
  2. Guard EndTransaction with TransactionStack.TransactionInProgress before calling it.
  3. Use a scope/using pattern so begin/end are paired automatically.
  4. Do not call EndTransaction in a catch/finally block when transaction creation itself failed.

Example fix

// before
finally { stack.EndTransaction(transaction); }

// after
finally
{
    if (stack.TransactionInProgress)
        stack.EndTransaction(transaction);
}
Defensive patterns

Strategy: validation

Validate before calling

if (!transactionStack.TransactionInProgress)
    return; // nothing to end
transactionStack.EndTransaction(transaction);

Type guard

bool HasOpenTransaction(TransactionStack stack) => stack.TransactionInProgress;

Try / catch

try
{
    transactionStack.EndTransaction(transaction);
}
catch (TransactionException ex) when (ex.Message.Contains("not transaction in progress"))
{
    // transaction already ended; ignore or log
}

Prevention

When it happens

Trigger: Calling transactionStack.EndTransaction(transaction) when no CreateTransaction/PushTransaction is open, or calling EndTransaction twice for the same transaction (the first call already popped it).

Common situations: Duplicate EndTransaction calls in exception-prone code paths; a finally block calling EndTransaction when the transaction was never created due to an earlier failure; mismatched transaction scoping across async continuations.

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/01c84ed44318a877. Report an issue: GitHub.

Appendix: source

Thrown at sources/core/Stride.Core.Design/Transactions/TransactionStack.cs:139

            currentPosition = 0;
            Cleared?.Invoke(this, EventArgs.Empty);
        }
    }

    /// <inheritdoc/>
    public IEnumerable<IReadOnlyTransaction> RetrieveAllTransactions()
    {
        return transactions;
    }

    public void CompleteTransaction(Transaction transaction)
    {
        lock (lockObject)
        {
            try
            {
                if (transactionsInProgress.Count == 0)
                    throw new TransactionException("There is not transaction in progress in the transaction stack.");

                if (transaction != transactionsInProgress.Pop())
                    throw new TransactionException("The transaction being completed is not that last created transaction.");

                // Check if we're completing the last transaction
                TransactionInProgress = transactionsInProgress.Count > 0;

                // Ignore the transaction if it is empty
                if (transaction.IsEmpty)
                    return;

                // If this transaction has no effect, discard it.
                if (transaction.Operations.All(x => !x.HasEffect))
                    return;

                // If we're not the last transaction, consider this transaction as an operation of its parent transaction
                if (TransactionInProgress)
                {

View on GitHub (pinned to 96fad776d2)