{"record":{"id":"d7b2bef69524f97c","repo":"remotion-dev/remotion","slug":"failed-to-create-shader","errorCode":null,"errorMessage":"Failed to create shader","messagePattern":"Failed to create shader","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/effects/src/tv-signal-off.ts","lineNumber":134,"sourceCode":"\nvoid main() {\n\tvec4 color = texture(uSource, vUv);\n\tvec3 sourceColor = color.a == 0.0 ? vec3(0.0) : color.rgb / color.a;\n\tvec3 bars = tvPattern(vUv);\n\tvec3 mixed = mix(sourceColor, bars, uAmount);\n\n\tfragColor = vec4(mixed * color.a, color.a);\n}\n`;\n\nconst compileShader = (\n\tgl: WebGL2RenderingContext,\n\ttype: number,\n\tsource: string,\n): WebGLShader => {\n\tconst shader = gl.createShader(type);\n\tif (!shader) {\n\t\tthrow new Error('Failed to create shader');\n\t}\n\n\tgl.shaderSource(shader, source);\n\tgl.compileShader(shader);\n\n\tif (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n\t\tconst info = gl.getShaderInfoLog(shader) ?? 'Unknown shader compile error';\n\t\tgl.deleteShader(shader);\n\t\tthrow new Error(info);\n\t}\n\n\treturn shader;\n};\n\nconst createProgram = (\n\tgl: WebGL2RenderingContext,\n\tvertexSource: string,\n\tfragmentSource: string,","sourceCodeStart":116,"sourceCodeEnd":152,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/tv-signal-off.ts#L116-L152","documentation":"Thrown by the tv-signal-off effect's internal compileShader helper when gl.createShader() returns null during effect setup. A null return from createShader means the WebGL2 context is lost, the GPU is out of memory, or the context was never validly initialized. The library fails fast rather than passing a null shader to subsequent GL calls, which would only produce a more confusing downstream error.","triggerScenarios":"The tvSignalOff effect's setup() calls createTvSignalOffState -> createProgram -> compileShader, and gl.createShader(gl.VERTEX_SHADER or gl.FRAGMENT_SHADER) returns null. This occurs when the WebGL2 context was acquired but is now in a WEBGL_lose_context lost state, or when the process has exhausted its GPU object allocation budget.","commonSituations":"Headless Chrome (Lambda, CI, Docker) with software rendering (SwiftShader) under memory pressure; too many concurrent Remotion render processes each holding their own GL context; a browser tab whose GL context was lost after a GPU driver crash or TDR; rendering on a machine where the GPU driver has crashed mid-render.","solutions":["Reduce the number of concurrent render processes / parallelism so fewer simultaneous WebGL2 contexts are alive","Ensure the headless browser has hardware GPU acceleration enabled (pass --use-gl=angle or the appropriate Chrome flags for your environment)","Listen for the webglcontextlost event on the canvas and retry the render or effect setup after webglcontextrestored fires","Update or replace GPU drivers; if using a VM, switch to one with GPU passthrough or a dedicated render GPU"],"exampleFix":"// before: many parallel renders exhaust GPU contexts\nconst {combineVideos} = await renderMedia({serveUrl, codec: 'h264', concurrency: 16});\n\n// after: lower concurrency to reduce simultaneous GL contexts\nawait renderMedia({serveUrl, codec: 'h264', concurrency: 4});","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  const state = setupTvSignalOffEffect(canvas);\n} catch (err) {\n  if (err instanceof Error && err.message === 'Failed to create shader') {\n    // Context is lost or GPU resources exhausted — retry the whole render\n    // after a context restoration event or process restart.\n    throw new Error('WebGL2 context lost during tv-signal-off setup. Retry the render.');\n  }\n  throw err;\n}","preventionTips":["Monitor the canvas webglcontextlost event and abort/retry the render proactively","Keep concurrent render process count low enough that GPU context limits are not exceeded","Ensure the headless browser has hardware GPU acceleration enabled via Chrome flags"],"tags":["webgl","gpu","tv-signal-off","resource-exhaustion","context-loss"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}