phaserjs/phaser · error · Error

Framebuffer status:

Error message

Framebuffer status: 

What it means

Thrown by WebGLFramebufferWrapper when gl.checkFramebufferStatus returns anything other than FRAMEBUFFER_COMPLETE while attaching a depth/stencil renderbuffer. The 'errors' map translates the GL status code to a human name (e.g. INCOMPLETE_ATTACHMENT) and the raw numeric is appended as fallback.

Source

Thrown at src/renderer/webgl/wrappers/WebGLFramebufferWrapper.js:256

            attachment = this.attachments[i];
            var attachmentPoint = attachment.attachmentPoint;
            var texture = attachment.texture;

            if (texture)
            {
                texture.isRenderTexture = true;
                gl.framebufferTexture2D(gl.FRAMEBUFFER, attachmentPoint, gl.TEXTURE_2D, texture.webGLTexture, 0);
            }
            else
            {
                // Check for completeness.
                // We must do this after the color attachments are created,
                // or the framebuffer will be incomplete and cannot accept
                // a renderbuffer.
                var complete = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
                if (complete !== gl.FRAMEBUFFER_COMPLETE)
                {
                    throw new Error('Framebuffer status: ' + (errors[complete] || complete));
                }

                var renderbuffer = gl.createRenderbuffer();
                glWrapper.updateBindingsRenderbuffer({
                    bindings:
                    {
                        renderbuffer: renderbuffer
                    }
                });
                gl.renderbufferStorage(gl.RENDERBUFFER, attachment.internalFormat, this.width, this.height);
                gl.framebufferRenderbuffer(gl.FRAMEBUFFER, attachmentPoint, gl.RENDERBUFFER, renderbuffer);

                // We could check for completeness again here,
                // but the invocations were checked during development,
                // and the renderbuffer is free of error.

                attachment.renderbuffer = renderbuffer;
            }

View on GitHub (pinned to 41be1e462b)

Solutions

  1. Read the appended status name/number and cross-reference the WebGL framebuffer completeness table for the exact cause.
  2. Ensure color attachments exist before requesting depth/stencil (the wrapper attaches depth after color).
  3. Match renderbuffer internalFormat to the context (use DEPTH_STENCIL / gl.DEPTH24_STENCIL8 on WebGL2).
  4. Verify attachment dimensions are non-zero and equal across all attachments.
  5. Fall back to a simpler framebuffer (depth only, or color only) if the combination is unsupported on the target GPU.

Example fix

// before
new WebGLFramebufferWrapper(renderer, {
  addDepthBuffer: true,
  addStencilBuffer: true
  // no color attachments -> incomplete
});

// after
new WebGLFramebufferWrapper(renderer, {
  colorAttachments: [colorTex],
  addDepthBuffer: true,
  addStencilBuffer: true
});
Defensive patterns

Strategy: try-catch

Validate before calling

function checkFBOComplete(gl) {
  const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
  return status === gl.FRAMEBUFFER_COMPLETE;
}

Try / catch

try { fb = new WebGLFramebufferWrapper(renderer, cfg); } catch (e) { if (/Framebuffer status/.test(e.message)) { console.error('FBO incomplete:', e.message); /* simplify cfg: drop stencil or change format */ } else throw e; }

Prevention

When it happens

Trigger: Requesting addDepthBuffer/addStencilBuffer with an unsupported internalFormat combination, zero-sized attachments, missing color attachments when depth is requested, unsupported texture formats for the context (WebGL1 vs WebGL2), or attaching a renderbuffer with mismatched dimensions.

Common situations: Enabling depth + stencil on a context/profile that does not expose DEPTH_STENCIL24_8; creating a framebuffer with non-power-of-two textures on WebGL1; passing incompatible internalFormat values; depth buffer dimensions out of sync with color after a resize; driver/GPU blacklists returning INCOMPLETE.

Related errors


AI-assisted analysis of phaserjs/phaser@41be1e462b (2026-08-13). Data as JSON: /api/errors/6dd046181c4f0947. Report an issue: GitHub.