{"record":{"id":"620e306b956222ee","repo":"remotion-dev/remotion","slug":"linear-progressive-blur-framebuffer-incomplete-0x","errorCode":null,"errorMessage":"Linear progressive blur framebuffer incomplete: 0x${status.toString(16)}","messagePattern":"Linear progressive blur framebuffer incomplete: 0x(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/effects/src/linear-progressive-blur/linear-progressive-blur-runtime.ts","lineNumber":205,"sourceCode":"\t\t0,\n\t\tgl.RGBA,\n\t\tgl.UNSIGNED_BYTE,\n\t\tnull,\n\t);\n\tgl.bindTexture(gl.TEXTURE_2D, null);\n\n\tgl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n\tgl.framebufferTexture2D(\n\t\tgl.FRAMEBUFFER,\n\t\tgl.COLOR_ATTACHMENT0,\n\t\tgl.TEXTURE_2D,\n\t\ttextureIntermediate,\n\t\t0,\n\t);\n\tconst status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);\n\tgl.bindFramebuffer(gl.FRAMEBUFFER, null);\n\tif (status !== gl.FRAMEBUFFER_COMPLETE) {\n\t\tthrow new Error(\n\t\t\t`Linear progressive blur framebuffer incomplete: 0x${status.toString(16)}`,\n\t\t);\n\t}\n\n\treturn {\n\t\tgl,\n\t\tprogramHorizontal,\n\t\tprogramVertical,\n\t\tvao,\n\t\tvbo,\n\t\ttextureSource,\n\t\ttextureIntermediate,\n\t\tframebuffer,\n\t\thorizontal: getUniforms(gl, programHorizontal),\n\t\tvertical: getUniforms(gl, programVertical),\n\t};\n};\n","sourceCodeStart":187,"sourceCodeEnd":223,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/linear-progressive-blur/linear-progressive-blur-runtime.ts#L187-L223","documentation":"Thrown by setupLinearProgressiveBlur() when gl.checkFramebufferStatus() returns something other than FRAMEBUFFER_COMPLETE after attaching the intermediate RGBA texture. The hex status code is interpolated, so the specific GL incomplete reason (e.g. 0x8cd6 UNSUPPORTED, 0x8cd5 INCOMPLETE_ATTACHMENT) is visible.","triggerScenarios":"The intermediate RGBA texture is incompatible with framebuffer rendering on this driver — typically because the chosen internal format (gl.RGBA) is not color-renderable on the implementation, the texture's dimensions are zero, or mip-level settings are inconsistent. Also seen when the texture storage was never allocated correctly (e.g. texImage2D failed silently).","commonSituations":"Drivers/GPUs where RGBA8 is not color-renderable in WebGL2 (rare but possible on stripped software rasterizers); a target canvas with zero width or height feeding `Math.max(1, target.width)`; outdated mesa/SwiftShader; a GPU-process crash leaving framebuffer state inconsistent.","solutions":["Decode the interpolated status hex: 0x8cd6=FRAMEBUFFER_UNSUPPORTED, 0x8cd5=INCOMPLETE_ATTACHMENT, 0x8cd7=MISSING_ATTACHMENT, 0x8219=INCOMPLETE_DIMENSIONS.","Confirm the target canvas has non-zero width/height before the effect mounts (Remotion compositions must render at >=1x1).","Switch GL backend to a complete implementation: `--gl=angle --angle-backend=swiftshader`.","Restart Chrome / the worker to rule out a crashed GPU process and retry.","Update GPU drivers/mesa; if persistent on one driver, report to @remotion/effects with the status code and driver string."],"exampleFix":"// before — composition can render at 0x0 during init, tripping INCOMPLETE_DIMENSIONS\n//   const comp = <Composition id=\"C\" component={...} width={0} height={0} fps={30} durationInFrames={90} />;\n\n// after\n//   const comp = <Composition id=\"C\" component={...} width={1920} height={1080} fps={30} durationInFrames={90} />;","handlingStrategy":"validation","validationCode":"// Validate dimensions + color-renderability before mounting the effect.\nfunction isValidBlurTarget(canvas: HTMLCanvasElement): boolean {\n  if (canvas.width < 1 || canvas.height < 1) return false; // INCOMPLETE_DIMENSIONS guard\n  const gl = canvas.getContext('webgl2');\n  if (!gl) return false;\n  const tex = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, tex);\n  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n  const fbo = gl.createFramebuffer(); gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);\n  gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tex, 0);\n  const complete = gl.checkFramebufferStatus(gl.FRAMEBUFFER) === gl.FRAMEBUFFER_COMPLETE;\n  gl.bindFramebuffer(gl.FRAMEBUFFER, null);\n  gl.deleteFramebuffer(fbo); gl.deleteTexture(tex);\n  return complete;\n}","typeGuard":null,"tryCatchPattern":"try {\n  renderWithLinearProgressiveBlur();\n} catch (err) {\n  if (err instanceof Error && err.message.startsWith('Linear progressive blur framebuffer incomplete')) {\n    // err.message contains the hex status — decode it, then switch GL backend or fix dimensions.\n    console.error(err.message);\n    await withGlBackend('swiftshader', () => renderWithLinearProgressiveBlur());\n  } else throw err;\n}","preventionTips":["Never render a composition at 0x0 — keep width/height >= 1 (the runtime clamps with Math.max(1, ...) but validate upstream).","Prefer SwiftShader/ANGLE for a complete framebuffer implementation on CI/Lambda.","Decode the interpolated status hex to pinpoint UNSUPPORTED vs INCOMPLETE_ATTACHMENT.","Restart the worker after GPU-process crashes to discard inconsistent framebuffer state."],"tags":["webgl","gpu","framebuffer","rendering","driver"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}