{"record":{"id":"6e3a5b53976f3bdc","repo":"MonoGame/MonoGame","slug":"rectangle-must-be-inside-the-texture-bounds","errorCode":null,"errorMessage":"Rectangle must be inside the texture bounds","messagePattern":"Rectangle must be inside the texture bounds","errorType":"validation","errorClass":"ArgumentException","httpStatus":null,"severity":"error","filePath":"MonoGame.Framework/Graphics/Texture2D.cs","lineNumber":788,"sourceCode":"            {\n                uint pixel = (uint)pixels[i];\n                pixels[i] = (int)((pixel & 0xFF00FF00) | ((pixel & 0x00FF0000) >> 16) | ((pixel & 0x000000FF) << 16));\n            }\n        }\n\n        private void ValidateParams<T>(int level, int arraySlice, Rectangle? rect, T[] data,\n            int startIndex, int elementCount, out Rectangle checkedRect) where T : struct\n        {\n            var textureBounds = new Rectangle(0, 0, Math.Max(width >> level, 1), Math.Max(height >> level, 1));\n            checkedRect = rect ?? textureBounds;\n            if (level < 0 || level >= LevelCount)\n                throw new ArgumentException(\"level must be smaller than the number of levels in this texture.\", \"level\");\n            if (arraySlice > 0 && !GraphicsDevice.GraphicsCapabilities.SupportsTextureArrays)\n                throw new ArgumentException(\"Texture arrays are not supported on this graphics device\", \"arraySlice\");\n            if (arraySlice < 0 || arraySlice >= ArraySize)\n                throw new ArgumentException(\"arraySlice must be smaller than the ArraySize of this texture and larger than 0.\", \"arraySlice\");\n            if (!textureBounds.Contains(checkedRect) || checkedRect.Width <= 0 || checkedRect.Height <= 0)\n                throw new ArgumentException(\"Rectangle must be inside the texture bounds\", \"rect\");\n            if (data == null)\n                throw new ArgumentNullException(\"data\");\n            var tSize = ReflectionHelpers.FastSizeOf<T>();\n            var fSize = Format.GetSize();\n            if (tSize > fSize || fSize % tSize != 0)\n                throw new ArgumentException(\"Type T is of an invalid size for the format of this texture.\", \"T\");\n            if (startIndex < 0 || startIndex >= data.Length)\n                throw new ArgumentException(\"startIndex must be at least zero and smaller than data.Length.\", \"startIndex\");\n            if (data.Length < startIndex + elementCount)\n                throw new ArgumentException(\"The data array is too small.\");\n\n            int dataByteSize;\n            if (Format.IsCompressedFormat())\n            {\n                int blockWidth, blockHeight;\n                Format.GetBlockSize(out blockWidth, out blockHeight);\n                // round x and y down to next multiple of block size; width and height up to next multiple of block size\n                // we need to use this rather than the old code where because ASTC Compressed Textures are NOT Powers of 2.","sourceCodeStart":770,"sourceCodeEnd":806,"githubUrl":"https://github.com/MonoGame/MonoGame/blob/1d71bbd0ff4071a03caa583aa3bc56b85924a819/MonoGame.Framework/Graphics/Texture2D.cs#L770-L806","documentation":"Thrown by Texture2D.ValidateParams as an ArgumentException when the supplied Rectangle is not fully inside the texture's bounds for the given level (or has non-positive width/height). Bounds are computed as (0,0, max(width>>level,1), max(height>>level,1)); a null rect defaults to the full bounds and always passes.","triggerScenarios":"Calling GetData/SetData with a rect whose X/Y is negative, whose right/bottom edge exceeds the (mip-level-scaled) texture size, or whose Width/Height <= 0; computing a sub-region from mouse/scroll coordinates that fall outside the texture.","commonSituations":"Pixel picking/scissor math that produces out-of-range rects; cropping a sub-texture with an off-by-one; forgetting that higher mip levels shrink the valid bounds.","solutions":["Clamp the rect to the level's bounds: Rectangle.Intersect(rect, textureBounds) before the call.","Ensure rect.Width and rect.Height are positive.","Pass null for the rect when you want the whole level."],"exampleFix":"// before\nvar r = new Rectangle(-5, 0, tex.Width, tex.Height);\ntex.GetData(0, r, data, 0, data.Length); // throws 457\n\n// after\nvar bounds = new Rectangle(0, 0, tex.Width, tex.Height);\nvar r = Rectangle.Intersect(requestedRect, bounds);\nif (r.Width <= 0 || r.Height <= 0) return;\ntex.GetData(0, r, data, 0, data.Length);","handlingStrategy":"validation","validationCode":"static Rectangle ClampRect(Texture2D tex, int level, Rectangle rect)\n{\n    var bounds = new Rectangle(0, 0, Math.Max(tex.Width >> level, 1), Math.Max(tex.Height >> level, 1));\n    var r = Rectangle.Intersect(rect, bounds);\n    if (r.Width <= 0 || r.Height <= 0) throw new ArgumentOutOfRangeException(nameof(rect), \"rect outside texture bounds\");\n    return r;\n}","typeGuard":"static bool IsInside(Texture2D tex, int level, Rectangle rect)\n{\n    var bounds = new Rectangle(0, 0, Math.Max(tex.Width >> level, 1), Math.Max(tex.Height >> level, 1));\n    return bounds.Contains(rect) && rect.Width > 0 && rect.Height > 0;\n}","tryCatchPattern":null,"preventionTips":["Intersect the rect with the level's bounds before GetData/SetData.","Ensure rect.Width/Height are positive.","Pass null for the rect when you want the entire level."],"tags":["monogame","graphics","texture2d","rectangle","bounds","validation","argument-exception"],"backgroundTag":null,"analyzedSha":"1d71bbd0ff4071a03caa583aa3bc56b85924a819","analyzedAt":"2026-08-13T17:10:33.625Z","schemaVersion":2},"datasetVersion":"2026-08-13T19:17:28.613Z"}