{"record":{"id":"fde8d2afc83aeec5","repo":"stride3d/stride","slug":"only-one-spritebatch-at-a-time-can-use-spritesortmode","errorCode":null,"errorMessage":"Only one SpriteBatch at a time can use SpriteSortMode.Immediate","messagePattern":"Only one SpriteBatch at a time can use SpriteSortMode\\.Immediate","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Graphics/BatchBase.cs","lineNumber":220,"sourceCode":"\n            textureUpdater = null;\n            if (Effect.Effect.HasParameter(TexturingKeys.Texture0))\n                textureUpdater = Effect.Parameters.GetAccessor(TexturingKeys.Texture0);\n            if (Effect.Effect.HasParameter(TexturingKeys.TextureCube0))\n                textureUpdater = Effect.Parameters.GetAccessor(TexturingKeys.TextureCube0);\n            if (Effect.Effect.HasParameter(TexturingKeys.Texture3D0))\n                textureUpdater = Effect.Parameters.GetAccessor(TexturingKeys.Texture3D0);\n\n            samplerUpdater = null;\n            if (Effect.Effect.HasParameter(TexturingKeys.Sampler))\n                samplerUpdater = Effect.Parameters.GetAccessor(TexturingKeys.Sampler);\n\n            // Immediate mode, then prepare for rendering here instead of End()\n            if (sessionSortMode == SpriteSortMode.Immediate)\n            {\n                if (ResourceContext.IsInImmediateMode)\n                {\n                    throw new InvalidOperationException(\"Only one SpriteBatch at a time can use SpriteSortMode.Immediate\");\n                }\n\n                PrepareForRendering();\n\n                ResourceContext.IsInImmediateMode = true;\n            }\n\n            // Sets to true isBeginCalled\n            isBeginCalled = true;\n        }\n\n        protected unsafe virtual void PrepareForRendering()\n        {\n            // Use LinearClamp for sampler state\n            var localSamplerState = samplerState ?? graphicsDevice.SamplerStates.LinearClamp;\n\n            // Sets the sampler state of the effect\n            if (samplerUpdater.HasValue)","sourceCodeStart":202,"sourceCodeEnd":238,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Graphics/BatchBase.cs#L202-L238","documentation":"BatchBase.Begin throws when SpriteSortMode.Immediate is requested while another batch is already in immediate mode (ResourceContext.IsInImmediateMode). Immediate mode renders during Begin, so only one such batch can be active per resource context at a time; a second would interleave draws from an un-Ended batch.","triggerScenarios":"Calling Begin(SpriteSortMode.Immediate, ...) on a second SpriteBatch (or SpriteFont batch) before End() was called on the first immediate-mode batch sharing the same graphics resource context.","commonSituations":"Nested immediate-mode sprite drawing (e.g. drawing UI inside an immediate batch), forgetting End on the first batch, or mixing SpriteBatch and other BatchBase-derived batches both set to Immediate in the same frame.","solutions":["Call End() on the first immediate-mode batch before beginning another one.","Use a deferred sort mode (e.g. SpriteSortMode.Deferred or BackToFront) for the second batch — only one Immediate batch is ever needed.","Refactor nested drawing so the inner content is drawn after the outer batch ends, or switch the outer batch to deferred."],"exampleFix":"// before\nbatchA.Begin(GraphicsContext, SpriteSortMode.Immediate);\nbatchB.Begin(GraphicsContext, SpriteSortMode.Immediate); // throws\n// after\nbatchA.Begin(GraphicsContext, SpriteSortMode.Immediate);\nbatchA.End();\nbatchB.Begin(GraphicsContext, SpriteSortMode.Immediate);","handlingStrategy":"validation","validationCode":"if (sortMode == SpriteSortMode.Immediate && ResourceContext.IsInImmediateMode)\n    sortMode = SpriteSortMode.Deferred; // downgrade instead of throwing\nbatch.Begin(context, sortMode);","typeGuard":null,"tryCatchPattern":"try { batch.Begin(ctx, SpriteSortMode.Immediate); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"Immediate\"))\n{\n    activeBatch.End();\n    batch.Begin(ctx, SpriteSortMode.Immediate);\n}","preventionTips":["Track and End the active immediate batch before starting another one.","Use Deferred sort mode for nested or secondary batches.","Structure rendering so batches are strictly sequential, never nested."],"tags":["graphics","spritebatch","rendering","concurrency"],"backgroundTag":"conflicting-config-options","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"}