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
- Read the appended status name/number and cross-reference the WebGL framebuffer completeness table for the exact cause.
- Ensure color attachments exist before requesting depth/stencil (the wrapper attaches depth after color).
- Match renderbuffer internalFormat to the context (use DEPTH_STENCIL / gl.DEPTH24_STENCIL8 on WebGL2).
- Verify attachment dimensions are non-zero and equal across all attachments.
- 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
- Provide color attachments before requesting depth/stencil.
- Use formats known to be supported on the target context version.
- Keep attachment sizes equal and non-zero.
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
- Color attachments must have the same dimensions
- Invalid buffer type for ARRAY_BUFFER
- Invalid buffer type for ELEMENT_ARRAY_BUFFER
- BatchHandler must have a name
- BatchHandlerStrip: Vertex count exceeds maximum per batch (
AI-assisted analysis of phaserjs/phaser@41be1e462b (2026-08-13).
Data as JSON: /api/errors/6dd046181c4f0947.
Report an issue: GitHub.