{"record":{"id":"990d4cbc67cfed93","repo":"remotion-dev/remotion","slug":"failed-to-create-webgl-texture-990d4c","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/pixel-dissolve.ts","lineNumber":308,"sourceCode":"\n\t\tconst vs = compileShader(gl, gl.VERTEX_SHADER, VERTEX_SHADER);\n\t\tconst fs = compileShader(gl, gl.FRAGMENT_SHADER, FRAGMENT_SHADER);\n\t\tconst program = linkProgram(gl, vs, fs);\n\t\tgl.deleteShader(vs);\n\t\tgl.deleteShader(fs);\n\n\t\tconst {vao, vbo} = createFullscreenQuad(gl);\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\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.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n\t\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n\t\tgl.bindTexture(gl.TEXTURE_2D, null);\n\n\t\treturn {\n\t\t\tgl,\n\t\t\tprogram,\n\t\t\tvao,\n\t\t\tvbo,\n\t\t\ttexture,\n\t\t\tuSource: gl.getUniformLocation(program, 'uSource'),\n\t\t\tuProgress: gl.getUniformLocation(program, 'uProgress'),\n\t\t\tuColumns: gl.getUniformLocation(program, 'uColumns'),","sourceCodeStart":290,"sourceCodeEnd":326,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/pixel-dissolve.ts#L290-L326","documentation":"Thrown by pixelDissolve setup when gl.createTexture() returns null after the program, VAO, VBO, and attribute wiring all succeeded. Textures are typically the most memory-hungry GL resource, so this is the most common allocation to fail when the GPU is under texture-memory pressure.","triggerScenarios":"pixelDissolve setup reaches createTexture() in the final block of the setup function; all earlier GL objects were created successfully but the texture unit cannot allocate. Often paired with large source video frames being uploaded to the same context.","commonSituations":"Rendering high-resolution (4K+) video where each frame uploads a fresh texture; many effects sharing a context; mobile or integrated GPUs with small VRAM; SwiftShader on Lambda with a memory-starved function; the source image exceeds MAX_TEXTURE_SIZE on the implementation.","solutions":["Lower the composition resolution or the source asset dimensions and re-render — texture allocation scales with frame pixel count.","Check `gl.getParameter(gl.MAX_TEXTURE_SIZE)` against your source dimensions and downscale assets that exceed it.","Increase Remotion Lambda function memory so SwiftShader has more texture budget.","Run fewer simultaneous texture-backed effects in one composition.","Verify the context is not lost with `gl.isContextLost()` and remount the effect if it is."],"exampleFix":"// before\nimport {pixelDissolve} from '@remotion/effects';\nconst effect = pixelDissolve();\n\n// after — gate on texture-size limits before mounting\nfunction supportsTextureForSize(w: number, h: number): boolean {\n  const c = document.createElement('canvas');\n  const gl = c.getContext('webgl2');\n  if (!gl) return false;\n  const maxSize = gl.getParameter(gl.MAX_TEXTURE_SIZE) as number;\n  return w <= maxSize && h <= maxSize && !gl.isContextLost();\n}","handlingStrategy":"try-catch","validationCode":"function textureFitsMax(gl: WebGL2RenderingContext, w: number, h: number): boolean {\n  if (gl.isContextLost()) return false;\n  const max = gl.getParameter(gl.MAX_TEXTURE_SIZE) as number;\n  return w <= max && h <= max;\n}\n// also probe allocation:\nfunction glCanCreateTexture(gl: WebGL2RenderingContext): boolean {\n  const t = gl.createTexture();\n  if (t) gl.deleteTexture(t);\n  return t !== null;\n}","typeGuard":null,"tryCatchPattern":"try {\n  pixelDissolve();\n} catch (err) {\n  if (/Failed to create WebGL texture/.test((err as Error).message)) {\n    // downscale source asset or reduce composition resolution, then retry\n  }\n  throw err;\n}","preventionTips":["Keep source asset dimensions at or below the GPU's MAX_TEXTURE_SIZE.","Render at the lowest acceptable composition resolution.","Avoid mounting many texture-heavy effects simultaneously.","Increase Lambda function memory so SwiftShader has texture headroom."],"tags":["webgl","gpu","memory","pixel-dissolve","texture","rendering"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}