{"record":{"id":"5ff4638c3cc524f5","repo":"stride3d/stride","slug":"this-operation-is-already-frozen","errorCode":null,"errorMessage":"This operation is already frozen.","messagePattern":"This operation is already frozen\\.","errorType":"exception","errorClass":"TransactionException","httpStatus":null,"severity":"error","filePath":"sources/core/Stride.Core.Design/Transactions/Operation.cs","lineNumber":72,"sourceCode":"    /// <summary>\n    /// Freezes the content of this operation, forbidding any subsequent rollback and rollforward.\n    /// </summary>\n    /// <remarks>This operation should release any reference that is not needed anymore by the operation.</remarks>\n    protected virtual void FreezeContent()\n    {\n        // Do nothing by default\n    }\n\n    protected virtual bool MergeInto(Operation otherOperation)\n    {\n        return false;\n    }\n\n    /// <inheritdoc/>\n    void IOperation.Freeze()\n    {\n        if (IsFrozen)\n            throw new TransactionException(\"This operation is already frozen.\");\n\n        FreezeContent();\n        IsFrozen = true;\n    }\n\n    /// <inheritdoc/>\n    void IOperation.Rollback()\n    {\n        if (IsFrozen)\n            throw new TransactionException(\"A disposed operation cannot be rollbacked.\");\n        if (inProgress)\n            throw new TransactionException(\"This operation is already in progress\");\n\n        inProgress = true;\n        Rollback();\n        inProgress = false;\n    }\n","sourceCodeStart":54,"sourceCodeEnd":90,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/core/Stride.Core.Design/Transactions/Operation.cs#L54-L90","documentation":"Thrown by IOperation.Freeze when the operation's IsFrozen flag is already set. Freezing is a one-time lifecycle step that finalizes the operation's content; freezing twice would violate the transaction system's invariants.","triggerScenarios":"Calling IOperation.Freeze() (or triggering it implicitly via transaction completion/dispose) on an Operation instance that was already frozen, e.g. completing a transaction twice or sharing one operation between transactions.","commonSituations":"Calling Complete()/Dispose() on a transaction more than once, reusing a single operation object across multiple transaction commits.","solutions":["Freeze each operation only once; guard with an IsFrozen check before calling","Create a new operation instead of reusing a frozen one","Track whether the owning transaction was already completed before calling Complete()"],"exampleFix":"// before\noperation.Freeze();\ntransaction.Complete();\noperation.Freeze(); // throws\n// after\nif (!operation.IsFrozen)\n    operation.Freeze();","handlingStrategy":"try-catch","validationCode":"if (operation.IsFrozen)\n    return; // already finalized, nothing to do","typeGuard":"bool CanFreeze(IOperation op) => op is Operation o && !o.IsFrozen;","tryCatchPattern":"try { operation.Freeze(); }\ncatch (TransactionException ex) when (ex.Message == \"This operation is already frozen.\")\n{\n    // idempotent: safe to ignore\n}","preventionTips":["Treat Freeze as one-time; guard with IsFrozen","Never reuse an operation across multiple transactions","Complete each transaction exactly once"],"tags":["transaction","frozen-operation","invalid-state"],"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"}