{"record":{"id":"2f84b3951688bfbf","repo":"stride3d/stride","slug":"begin-must-be-called-before-functionname","errorCode":null,"errorMessage":"Begin must be called before functionName","messagePattern":"Begin must be called before functionName","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"sources/engine/Stride.Graphics/BatchBase.cs","lineNumber":271,"sourceCode":"            mutablePipeline.Update();\n\n            // Bind pipeline\n            if (mutablePipeline.State.DepthStencilState.StencilEnable)\n                GraphicsContext.CommandList.SetStencilReference(stencilReferenceValue);\n            GraphicsContext.CommandList.SetPipelineState(mutablePipeline.CurrentState);\n\n            // Bind VB/IB\n            if (ResourceContext.VertexBuffer != null)\n                GraphicsContext.CommandList.SetVertexBuffer(0, ResourceContext.VertexBuffer, 0, vertexStructSize);\n            if (ResourceContext.IndexBuffer != null)\n                GraphicsContext.CommandList.SetIndexBuffer(ResourceContext.IndexBuffer, 0, indexStructSize == sizeof(int));\n        }\n\n        protected void CheckBeginHasBeenCalled(string functionName)\n        {\n            if (!isBeginCalled)\n            {\n                throw new InvalidOperationException(\"Begin must be called before \" + functionName);\n            }\n        }\n\n        protected void CheckEndHasBeenCalled(string functionName)\n        {\n            if (isBeginCalled)\n            {\n                throw new InvalidOperationException(\"End must be called before \" + functionName);\n            }\n        }\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","sourceCodeStart":253,"sourceCodeEnd":289,"githubUrl":"https://github.com/stride3d/stride/blob/96fad776d210c221682aac1ccdf4c79dc046fc38/sources/engine/Stride.Graphics/BatchBase.cs#L253-L289","documentation":"BatchBase (the base class of SpriteBatch and UI batch renderers) tracks whether Begin() has been called via the isBeginCalled flag. Methods that draw or flush the batch (End, Draw) call CheckBeginHasBeenCalled and throw if the batch lifecycle was not started. This guards against rendering with an unset effect, viewport, or sampler state that only Begin() configures.","triggerScenarios":"Calling batch.End(), batch.Draw(...) or batch.Flush without a preceding successful batch.Begin(...); calling End twice after Begin already consumed; an exception thrown inside Begin that skipped its final flag set while the caller continues to Draw/End.","commonSituations":"Copy-pasted render loops where the Begin call was deleted or commented out; early returns between Begin and End causing a second End on a stale batch object; reusing a batch across frames where the Begin call is in a branch that did not execute (e.g. empty draw list skip logic).","solutions":["Ensure Begin(...) is called on the batch immediately before any Draw/End calls for that batch instance.","Check that a previous exception did not abort between Begin and Draw; wrap draw code so state flags stay consistent.","Verify you are calling Begin/End on the same batch instance, not two different batch objects.","Do not call End twice; restructure so each Begin is paired with exactly one End."],"exampleFix":"// before\nspriteBatch.End();\n// after\nspriteBatch.Begin(spriteSortMode, blendState);\nspriteBatch.Draw(texture, position);\nspriteBatch.End();","handlingStrategy":"try-catch","validationCode":"if (!batchStarted) throw new InvalidOperationException(\"Call Begin before Draw/End\");\n// track it yourself:\nbool batchStarted = false;","typeGuard":"bool CanDraw(BatchBase b) => b != null && batchStarted;","tryCatchPattern":"try { spriteBatch.Draw(...); spriteBatch.End(); }\ncatch (InvalidOperationException ex) when (ex.Message.StartsWith(\"Begin must be called\"))\n{\n    log.Warn(\"SpriteBatch used without Begin\");\n}","preventionTips":["Always pair Begin/End adjacent in the same method.","Use try/finally around End after Begin.","Keep one batch instance per render phase."],"tags":["graphics","rendering","invalid-state","spritebatch"],"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"}