{"record":{"id":"7c2848692543da60","repo":"stride3d/stride","slug":"cannot-end-one-spritebatch-while-another-is-using","errorCode":null,"errorMessage":"Cannot end one SpriteBatch while another is using SpriteSortMode.Immediate","messagePattern":"Cannot end one SpriteBatch while another is using SpriteSortMode\\.Immediate","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Graphics/BatchBase.cs","lineNumber":299,"sourceCode":"        }\n\n        /// <summary>\n        /// Flushes the sprite batch and restores the device state to how it was before Begin was called.\n        /// </summary>\n        public void End()\n        {\n            CheckBeginHasBeenCalled(\"End\");\n\n            if (sortMode == SpriteSortMode.Immediate)\n            {\n                ResourceContext.IsInImmediateMode = false;\n            }\n            else if (drawsQueueCount > 0)\n            {\n                // Draw the queued sprites now.\n                if (ResourceContext.IsInImmediateMode)\n                {\n                    throw new InvalidOperationException(\"Cannot end one SpriteBatch while another is using SpriteSortMode.Immediate\");\n                }\n\n                // If not immediate, then setup and render all sprites\n                PrepareForRendering();\n                FlushBatch();\n            }\n\n            ResourceContext = null;\n\n            // We are with begin pair\n            isBeginCalled = false;\n        }\n\n        private void SortSprites()\n        {\n            IComparer<int> comparer;\n\n            switch (sortMode)","sourceCodeStart":281,"sourceCodeEnd":317,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Graphics/BatchBase.cs#L281-L317","documentation":"In SpriteSortMode.Immediate the batch draws sprites directly as they are submitted. If one SpriteBatch is in Immediate mode, ending a second SpriteBatch (with queued draws) would change device state and break the in-flight immediate rendering, so End throws this InvalidOperationException.","triggerScenarios":"spriteBatchA.Begin(Immediate, ...) is active and batchSizeB.End() is called while spriteBatchB still has queued draws (drawsQueueCount > 0); interleaving an immediate-mode batch with a deferred batch's End without ending the immediate batch first.","commonSituations":"Mixing an immediate-mode SpriteBatch for per-pixel custom effects with a normal deferred SpriteBatch for text/UI in the same frame; forgetting End on the immediate batch before flushing the other one.","solutions":["Call End() on the Immediate-mode SpriteBatch before ending any other batch with pending draws.","Restructure rendering so Immediate and deferred batches are not interleaved.","Switch the immediate batch to a deferred sort mode (e.g. BackToFront) if immediate semantics are not required.","Ensure End is called on the immediate batch even on early-exit paths (try/finally)."],"exampleFix":"// before\nimmediateBatch.Begin(SpriteSortMode.Immediate, blend);\ndeferredBatch.Begin(SpriteSortMode.Deferred, blend);\ndeferredBatch.End(); // throws\n// after\nimmediateBatch.Begin(SpriteSortMode.Immediate, blend);\nimmediateBatch.End();\ndeferredBatch.Begin(SpriteSortMode.Deferred, blend);\ndeferredBatch.End();","handlingStrategy":"validation","validationCode":"// before ending a deferred batch, ensure no immediate batch is active\nbool immediateActive = false; // track when Begin(SpriteSortMode.Immediate, ...) is called\nif (!immediateActive) deferredBatch.End();","typeGuard":"bool CanEndBatch(BatchBase b) => !immediateBatchActive || ReferenceEquals(b, immediateBatch);","tryCatchPattern":"try { deferredBatch.End(); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"SpriteSortMode.Immediate\"))\n{\n    immediateBatch.End();\n    deferredBatch.End();\n}","preventionTips":["End immediate-mode batches before other batches.","Avoid interleaving Immediate and deferred batches.","Track which batch is in Immediate mode."],"tags":["graphics","spritebatch","rendering","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-15T23:17:13.987Z"}