{"record":{"id":"13d5e805c55b3514","repo":"remotion-dev/remotion","slug":"failed-to-create-webgl-texture-13d5e8","errorCode":null,"errorMessage":"Failed to create WebGL texture","messagePattern":"Failed to create WebGL texture","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/effects/src/halftone.ts","lineNumber":458,"sourceCode":"\t\tif (!vbo) {\n\t\t\tthrow new Error('Failed to create WebGL buffer');\n\t\t}\n\n\t\tgl.bindBuffer(gl.ARRAY_BUFFER, vbo);\n\t\tgl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW);\n\n\t\tconst aPos = gl.getAttribLocation(program, 'aPos');\n\t\tconst aUv = gl.getAttribLocation(program, 'aUv');\n\t\tgl.enableVertexAttribArray(aPos);\n\t\tgl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 16, 0);\n\t\tgl.enableVertexAttribArray(aUv);\n\t\tgl.vertexAttribPointer(aUv, 2, gl.FLOAT, false, 16, 8);\n\n\t\tgl.bindVertexArray(null);\n\n\t\tconst texture = gl.createTexture();\n\t\tif (!texture) {\n\t\t\tthrow new Error('Failed to create WebGL texture');\n\t\t}\n\n\t\tgl.bindTexture(gl.TEXTURE_2D, texture);\n\t\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n\t\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n\t\tgl.bindTexture(gl.TEXTURE_2D, null);\n\n\t\tconst colorCanvas = document.createElement('canvas');\n\t\tcolorCanvas.width = 1;\n\t\tcolorCanvas.height = 1;\n\t\tconst colorCtx = colorCanvas.getContext('2d', {willReadFrequently: true});\n\t\tif (!colorCtx) {\n\t\t\tthrow new Error('Failed to acquire 2D context for color parsing');\n\t\t}\n\n\t\treturn {\n\t\t\tgl,\n\t\t\tprogram,","sourceCodeStart":440,"sourceCodeEnd":476,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/halftone.ts#L440-L476","documentation":"Thrown in setup() of the halftone effect when gl.createTexture() returns null. The effect allocates one source texture to receive each incoming frame; null means the GL implementation refused another texture object — texture-budget limits or context loss.","triggerScenarios":"Allocating the halftone source texture alongside many other live textures; very large frame dimensions on a GPU with low texture memory; context-lost state.","commonSituations":"Compositions with many media layers feeding WebGL2 effects; headless software GL with stingy texture limits; rendering after a GPU crash.","solutions":["Check gl.isContextLost(); restart the render if true.","Reduce media-layer count feeding WebGL2 effects or lower output resolution.","Render on hardware with adequate texture memory; avoid pure-software GL for large frames.","Update the GPU driver."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"function canCreateTexture(canvas: HTMLCanvasElement, width: number, height: number): boolean {\n  const gl = canvas.getContext('webgl2');\n  if (!gl) return false;\n  const tex = gl.createTexture();\n  if (!tex) return false;\n  gl.bindTexture(gl.TEXTURE_2D, tex);\n  try {\n    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n  } catch {\n    gl.deleteTexture(tex);\n    return false;\n  }\n  gl.deleteTexture(tex);\n  return true;\n}","typeGuard":null,"tryCatchPattern":"try {\n  // ...use halftone()\n} catch (e) {\n  if (e instanceof Error && /Failed to create WebGL texture/.test(e.message)) {\n    // reduce resolution / media layers, or restart on context loss\n  } else throw e;\n}","preventionTips":["Keep total media-layer count feeding WebGL2 effects within GPU texture memory.","Lower output resolution when rendering on low-memory GPUs.","Restart the render after a context-lost event."],"tags":["webgl","halftone","gpu-resources","texture","context-loss"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}