{"record":{"id":"4c1e8c3db0a24072","repo":"phaserjs/phaser","slug":"color-attachments-must-have-the-same-dimensions","errorCode":null,"errorMessage":"Color attachments must have the same dimensions","messagePattern":"Color attachments must have the same dimensions","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/renderer/webgl/wrappers/WebGLFramebufferWrapper.js","lineNumber":142,"sourceCode":"        this.attachments = [];\n\n        if (!this.useCanvas)\n        {\n            for (var i = 0; i < colorAttachments.length; i++)\n            {\n                this.attachments.push({\n                    texture: colorAttachments[i],\n                    attachmentPoint: gl.COLOR_ATTACHMENT0 + i\n                });\n\n                if (i === 0)\n                {\n                    this.width = colorAttachments[i].width;\n                    this.height = colorAttachments[i].height;\n                }\n                else if (colorAttachments[i].width !== this.width || colorAttachments[i].height !== this.height)\n                {\n                    throw new Error('Color attachments must have the same dimensions');\n                }\n            }\n\n            // Only generate depth and stencil buffers if color attachments are provided.\n            // Generate a depth-stencil buffer if both are requested.\n            // These must be attached after the color attachments,\n            // so that the framebuffer is complete when they're attached.\n            if (addDepthBuffer && addStencilBuffer)\n            {\n                this.attachments.push({\n                    attachmentPoint: gl.DEPTH_STENCIL_ATTACHMENT,\n                    internalFormat: gl.DEPTH_STENCIL\n                });\n            }\n            else if (addDepthBuffer)\n            {\n                this.attachments.push({\n                    attachmentPoint: gl.DEPTH_ATTACHMENT,","sourceCodeStart":124,"sourceCodeEnd":160,"githubUrl":"https://github.com/phaserjs/phaser/blob/41be1e462bc600064e498cba370bfa8c5c055a22/src/renderer/webgl/wrappers/WebGLFramebufferWrapper.js#L124-L160","documentation":"Thrown by WebGLFramebufferWrapper when creating a framebuffer with multiple color attachments where attachment[i] (i>0) has a width or height different from attachment[0]. WebGL MRT (multiple render targets) requires all color attachments to be the same dimensions, so the wrapper rejects mismatched inputs at construction.","triggerScenarios":"Constructing a WebGLFramebufferWrapper with a colorAttachments array whose textures have differing .width/.height; passing a render texture and a game texture of different sizes; resizing one attachment but not the others before rebuilding the framebuffer.","commonSituations":"Custom multi-target render passes (e.g. G-buffer with position + normals + albedo) where textures were allocated at different sizes; compositing pipelines that mix a half-res and full-res target into one framebuffer; post-process chains where one buffer was resized on canvas resize and another was not.","solutions":["Ensure all color attachments are created with identical width and height.","Recreate/resize every attachment together on canvas resize before rebuilding the framebuffer.","Allocate targets from a shared size constant.","If different sizes are genuinely needed, use separate framebuffers and composite, not MRT."],"exampleFix":"// before\nnew WebGLFramebufferWrapper(renderer, {\n  colorAttachments: [texA, texB] // texA 1024x768, texB 512x512 -> throws\n});\n\n// after\nconst w = 1024, h = 768;\ntexB = renderer.createTexture(w, h);\nnew WebGLFramebufferWrapper(renderer, { colorAttachments: [texA, texB] });","handlingStrategy":"validation","validationCode":"const w0 = colorAttachments[0].width, h0 = colorAttachments[0].height;\nif (!colorAttachments.every(t => t.width === w0 && t.height === h0)) {\n  throw new Error('Color attachments differ in size');\n}","typeGuard":"function attachmentsSameSize(atts) {\n  if (!atts.length) return true;\n  const { width, height } = atts[0];\n  return atts.every(t => t.width === width && t.height === height);\n}","tryCatchPattern":null,"preventionTips":["Allocate all attachments from one shared (w,h).","Recreate every attachment on canvas resize.","Keep MRT targets in a single descriptor object."],"tags":["renderer","webgl","framebuffer","webgl-wrapper","phaser4"],"backgroundTag":null,"analyzedSha":"41be1e462bc600064e498cba370bfa8c5c055a22","analyzedAt":"2026-08-13T04:23:39.729Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}