{"record":{"id":"1a93c022e31ad685","repo":"remotion-dev/remotion","slug":"drop-shadow-framebuffer-incomplete-0x-status-tos","errorCode":null,"errorMessage":"Drop shadow framebuffer incomplete: 0x${status.toString(16)}","messagePattern":"Drop shadow framebuffer incomplete: 0x(.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/effects/src/drop-shadow/drop-shadow-runtime.ts","lineNumber":305,"sourceCode":"\t);\n};\n\nconst setFramebufferTexture = (\n\tgl: WebGL2RenderingContext,\n\tframebuffer: WebGLFramebuffer,\n\ttexture: WebGLTexture,\n): void => {\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\ttexture,\n\t\t0,\n\t);\n\tconst status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);\n\tif (status !== gl.FRAMEBUFFER_COMPLETE) {\n\t\tthrow new Error(\n\t\t\t`Drop shadow framebuffer incomplete: 0x${status.toString(16)}`,\n\t\t);\n\t}\n};\n\nconst setBlurUniforms = ({\n\tgl,\n\tuniforms,\n\tradius,\n\twidth,\n\theight,\n}: {\n\treadonly gl: WebGL2RenderingContext;\n\treadonly uniforms: DropShadowState['horizontal'];\n\treadonly radius: number;\n\treadonly width: number;\n\treadonly height: number;\n}): void => {","sourceCodeStart":287,"sourceCodeEnd":323,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/drop-shadow/drop-shadow-runtime.ts#L287-L323","documentation":"Thrown by the drop-shadow runtime's setFramebufferTexture helper when gl.checkFramebufferStatus returns a value other than FRAMEBUFFER_COMPLETE. The status hex is embedded in the message so the specific cause can be identified (e.g. 0x8cd6 FRAMEBUFFER_INCOMPLETE_ATTACHMENT, 0x8cd5 FRAMEBUFFER_UNSUPPORTED). The runtime attaches an RGBA/UNSIGNED_BYTE texture, so incompleteness usually means zero dimensions, dimensions exceeding GPU limits, or an unsupported format on a non-conformant driver.","triggerScenarios":"setFramebufferTexture is called per apply() with the shadow textures sized to width x height. If width or height is 0, exceeds MAX_TEXTURE_SIZE, or the driver rejects RGBA/UNSIGNED_BYTE render targets, the framebuffer is incomplete. The hex code in the message pinpoints the failure: 0x8cd6 (attachment), 0x8cd9 (dimensions), 0x8cdd (unsupported).","commonSituations":"Rendering a composition whose dimensions momentarily collapse to 0 (e.g. a transition that animates scale to 0); rendering at resolutions beyond the GPU's MAX_TEXTURE_SIZE; non-conformant drivers that refuse RGBA8 render targets; nested effects producing zero-size intermediate buffers.","solutions":["Decode the status hex: 0x8cd6 = incomplete attachment, 0x8cd9 = dimensions mismatch / zero, 0x8cdd = unsupported format.","Ensure composition width and height are always positive integers and never animate to 0.","Keep frame dimensions under gl.getParameter(gl.MAX_TEXTURE_SIZE) (commonly 4096 or 8192 on desktop, 4096 on mobile).","Update GPU drivers if RGBA8 render targets are wrongly rejected.","If the failure comes from a nested effect chain, render through an intermediate Composition at safe dimensions."],"exampleFix":"// before\nconst w = Math.round(interpolate(frame, [0, 30], [1920, 0]));\n\n// after — keep a 1px floor and stay a power-of-two-safe positive integer\nconst w = Math.max(1, Math.round(interpolate(frame, [0, 30], [1920, 2])));","handlingStrategy":"validation","validationCode":"const safeSize = (n) =>\n  typeof n === 'number' && Number.isFinite(n) && n > 0 ? Math.round(n) : null;\n\nconst w = safeSize(width);\nconst h = safeSize(height);\nif (w === null || h === null) {\n  // skip the drop-shadow pass for this frame instead of crashing\n}","typeGuard":"const MAX = (() => {\n  try {\n    const gl = document.createElement('canvas').getContext('webgl2');\n    return gl ? gl.getParameter(gl.MAX_TEXTURE_SIZE) : 4096;\n  } catch {\n    return 4096;\n  }\n})();\n\nconst isSafeFrameSize = (w: unknown, h: unknown): boolean =>\n  typeof w === 'number' &&\n  typeof h === 'number' &&\n  Number.isFinite(w) &&\n  Number.isFinite(h) &&\n  w > 0 &&\n  h > 0 &&\n  w <= MAX &&\n  h <= MAX;","tryCatchPattern":null,"preventionTips":["Never animate composition width/height through 0; clamp to a 1px floor.","Keep frame dimensions under gl.getParameter(gl.MAX_TEXTURE_SIZE).","Decode the embedded status hex (0x8cd6 attachment, 0x8cd9 dimensions, 0x8cdd unsupported) when triaging.","Update GPU drivers if RGBA8 render targets are wrongly rejected."],"tags":["webgl2","drop-shadow","framebuffer","render-target","dimensions","gpu-driver"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}