{"record":{"id":"72069a4f2c0c86b6","repo":"remotion-dev/remotion","slug":"failed-to-create-exposure-texture","errorCode":null,"errorMessage":"Failed to create exposure texture","messagePattern":"Failed to create exposure texture","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/effects/src/exposure.ts","lineNumber":155,"sourceCode":"\tgl.attachShader(program, vertexShader);\n\tgl.attachShader(program, fragmentShader);\n\tgl.linkProgram(program);\n\tgl.deleteShader(vertexShader);\n\tgl.deleteShader(fragmentShader);\n\n\tif (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n\t\tconst log = gl.getProgramInfoLog(program);\n\t\tgl.deleteProgram(program);\n\t\tthrow new Error(`Exposure shader link failed: ${log ?? '(no log)'}`);\n\t}\n\n\treturn program;\n};\n\nconst createTexture = (gl: WebGL2RenderingContext): WebGLTexture => {\n\tconst texture = gl.createTexture();\n\tif (!texture) {\n\t\tthrow new Error('Failed to create exposure texture');\n\t}\n\n\tgl.bindTexture(gl.TEXTURE_2D, texture);\n\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);\n\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);\n\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n\tgl.bindTexture(gl.TEXTURE_2D, null);\n\treturn texture;\n};\n\nconst setupExposure = (target: HTMLCanvasElement): ExposureState => {\n\tconst gl = target.getContext('webgl2', {\n\t\tpremultipliedAlpha: true,\n\t\talpha: true,\n\t\tpreserveDrawingBuffer: true,\n\t});\n\tif (!gl) {","sourceCodeStart":137,"sourceCodeEnd":173,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/exposure.ts#L137-L173","documentation":"Thrown inside createTexture() in exposure.ts when gl.createTexture() returns null (exposure.ts:154-156). A null texture means the driver would not allocate another texture object — context lost or texture pool/GPU memory exhausted. The exposure source sampler has no target, so setup aborts.","triggerScenarios":"setupExposure() calls createTexture() (the source texture used by uSource) and gl.createTexture() returns null. This occurs when the WebGL2 context is lost or when leaked textures from un-cleaned effects have exhausted the driver's texture-object/memory budget.","commonSituations":"Long-running Studio sessions leaking textures; compositions with many simultaneous exposure() layers; headless CI hosts with limited GPU memory; contexts left lost after a GPU crash.","solutions":["Render with --gl=angle (CLI) / chromiumOptions.gl='angle' (SSR) / Angle (Studio).","Ensure effect cleanup() runs (it calls gl.deleteTexture on textureSource); never hold stale exposure states.","Cut the simultaneous WebGL2 effect count and reuse identical exposure() params via calculateKey.","Check gl.isContextLost() and restore the context before retrying.","Move to a host with more GPU memory or a consistent software GL path."],"exampleFix":"// before\nconst texture = gl.createTexture();\nif (!texture) {\n  throw new Error('Failed to create exposure texture');\n}\n\n// after (caller guard)\nif (gl.isContextLost()) {\n  // defer exposure setup until webglcontextrestored\n}","handlingStrategy":"try-catch","validationCode":"const canAllocateTexture = (gl: WebGL2RenderingContext): boolean => {\n  if (gl.isContextLost()) return false;\n  const probe = gl.createTexture();\n  if (!probe) return false;\n  gl.deleteTexture(probe);\n  return true;\n};","typeGuard":null,"tryCatchPattern":"try {\n  // apply exposure(); for a custom canvas: const state = setupExposure(canvas);\n} catch (err) {\n  if (err instanceof Error && err.message === 'Failed to create exposure texture') {\n    // free other effects, restore context, retry on Angle\n    throw err;\n  }\n  throw err;\n}","preventionTips":["Render with Angle (--gl=angle / chromiumOptions.gl='angle').","Ensure cleanup() runs so textures are deleted, not leaked.","Limit simultaneous WebGL2 effects; reuse identical exposure() params.","Handle webglcontextlost and restore before retrying."],"tags":["webgl","texture","resource-allocation","gpu","exposure","setup"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}