{"record":{"id":"a9d140181fca8d4e","repo":"MonoGame/MonoGame","slug":"you-cannot-modify-the-depth-stencil-state-after-it","errorCode":null,"errorMessage":"You cannot modify the depth stencil state after it has been bound to the graphics device!","messagePattern":"You cannot modify the depth stencil state after it has been bound to the graphics device!","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"MonoGame.Framework/Graphics/States/DepthStencilState.cs","lineNumber":425,"sourceCode":"                _twoSidedStencilMode = value;\r\n            }\r\n        }\n\n        internal void BindToGraphicsDevice(GraphicsDevice device)\r\n        {\r\n            if (_defaultStateObject)\r\n                throw new InvalidOperationException(\"You cannot bind a default state object.\");\r\n            if (GraphicsDevice != null && GraphicsDevice != device)\r\n                throw new InvalidOperationException(\"This depth stencil state is already bound to a different graphics device.\");\r\n            GraphicsDevice = device;\r\n        }\r\n\r\n        internal void ThrowIfBound()\r\n        {\r\n            if (_defaultStateObject)\r\n                throw new InvalidOperationException(\"You cannot modify a default depth stencil state object.\");\r\n            if (GraphicsDevice != null)\r\n                throw new InvalidOperationException(\"You cannot modify the depth stencil state after it has been bound to the graphics device!\");\r\n        }\r\n\n        /// <summary>\n        /// Creates a new instance of the DepthStencilState class with default values.\n        /// </summary>\r\n        public DepthStencilState ()\r\n\t\t{\r\n            DepthBufferEnable = true;\r\n            DepthBufferWriteEnable = true;\r\n\t\t\tDepthBufferFunction = CompareFunction.LessEqual;\r\n\t\t\tStencilEnable = false;\r\n\t\t\tStencilFunction = CompareFunction.Always;\r\n\t\t\tStencilPass = StencilOperation.Keep;\r\n\t\t\tStencilFail = StencilOperation.Keep;\r\n\t\t\tStencilDepthBufferFail = StencilOperation.Keep;\r\n\t\t\tTwoSidedStencilMode = false;\r\n\t\t\tCounterClockwiseStencilFunction = CompareFunction.Always;\r\n\t\t\tCounterClockwiseStencilFail = StencilOperation.Keep;\r","sourceCodeStart":407,"sourceCodeEnd":443,"githubUrl":"https://github.com/MonoGame/MonoGame/blob/1d71bbd0ff4071a03caa583aa3bc56b85924a819/MonoGame.Framework/Graphics/States/DepthStencilState.cs#L407-L443","documentation":"Thrown by DepthStencilState.ThrowIfBound when attempting to modify any property of a user-created DepthStencilState after it has been bound to a GraphicsDevice. Post-binding mutation is blocked to prevent managed/native state desynchronization.","triggerScenarios":"Assigning myState to GraphicsDevice.DepthStencilState (triggering binding), then later modifying myState.StencilEnable or any other property. Every setter calls ThrowIfBound(), checking GraphicsDevice != null at DepthStencilState.cs:423-424.","commonSituations":"Toggling stencil or depth-write per-frame on a shared state object. Setting GraphicsDevice.DepthStencilState early, then adjusting in a later frame. Render-loop code that mutates state objects that were already applied. Refactoring that moved property sets after first use.","solutions":["Configure all DepthStencilState properties before assigning to GraphicsDevice.DepthStencilState.","Pre-create multiple DepthStencilState instances for different modes and switch between them per-frame.","Create a new instance when settings must change (be mindful of allocation cost in hot paths)."],"exampleFix":"// before\nvar ds = new DepthStencilState { DepthBufferEnable = true };\nGraphicsDevice.DepthStencilState = ds; // binds\nds.StencilEnable = true; // throws - already bound\n\n// after\nvar ds = new DepthStencilState\n{\n    DepthBufferEnable = true,\n    StencilEnable = true\n}; // configure fully before binding\nGraphicsDevice.DepthStencilState = ds;","handlingStrategy":"validation","validationCode":"// Configure all properties before binding\nvar ds = new DepthStencilState\n{\n    DepthBufferEnable = true,\n    DepthBufferWriteEnable = false,\n    StencilEnable = true\n};\n// Only assign (bind) after all properties are set\nGraphicsDevice.DepthStencilState = ds;","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Set all DepthStencilState properties before assigning to GraphicsDevice.DepthStencilState.","Pre-create multiple instances for per-frame mode switching.","Never mutate a state after it has been assigned to the device."],"tags":["monogame","depthstencilstate","immutable-after-bind","state-object","invalid-operation","graphics","render-state","z-buffer"],"backgroundTag":null,"analyzedSha":"1d71bbd0ff4071a03caa583aa3bc56b85924a819","analyzedAt":"2026-08-13T17:10:33.625Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}