{"record":{"id":"6dce7ff31010d497","repo":"remotion-dev/remotion","slug":"failed-to-create-webgl-resources","errorCode":null,"errorMessage":"Failed to create WebGL resources","messagePattern":"Failed to create WebGL resources","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/effects/src/tv-signal-off.ts","lineNumber":187,"sourceCode":"\t\tgl.deleteProgram(program);\n\t\tthrow new Error(info);\n\t}\n\n\treturn program;\n};\n\nconst createTvSignalOffState = (\n\tgl: WebGL2RenderingContext,\n\tvertexSource: string,\n\tfragmentSource: string,\n): TvSignalOffState => {\n\tconst program = createProgram(gl, vertexSource, fragmentSource);\n\tconst vao = gl.createVertexArray();\n\tconst vbo = gl.createBuffer();\n\tconst texture = gl.createTexture();\n\n\tif (!vao || !vbo || !texture) {\n\t\tthrow new Error('Failed to create WebGL resources');\n\t}\n\n\tgl.bindVertexArray(vao);\n\tgl.bindBuffer(gl.ARRAY_BUFFER, vbo);\n\tgl.bufferData(\n\t\tgl.ARRAY_BUFFER,\n\t\tnew Float32Array([-1, -1, 0, 0, 1, -1, 1, 0, -1, 1, 0, 1, 1, 1, 1, 1]),\n\t\tgl.STATIC_DRAW,\n\t);\n\n\tconst aPos = gl.getAttribLocation(program, 'aPos');\n\tconst aUv = gl.getAttribLocation(program, 'aUv');\n\tgl.enableVertexAttribArray(aPos);\n\tgl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 16, 0);\n\tgl.enableVertexAttribArray(aUv);\n\tgl.vertexAttribPointer(aUv, 2, gl.FLOAT, false, 16, 8);\n\n\tgl.bindTexture(gl.TEXTURE_2D, texture);","sourceCodeStart":169,"sourceCodeEnd":205,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/tv-signal-off.ts#L169-L205","documentation":"Thrown by createTvSignalOffState when any of gl.createVertexArray(), gl.createBuffer(), or gl.createTexture() returns null during the tv-signal-off effect setup. The library bundles all three checks into one guard and fails fast, because rendering requires all three resources to be valid.","triggerScenarios":"After the shader program is built, createTvSignalOffState calls createVertexArray, createBuffer, and createTexture in sequence. If any returns null — indicating a lost context or exhausted GPU object pool — the combined null check at line 186 fires.","commonSituations":"Context loss after GPU driver reset; server-side rendering with many parallel WebGL2 contexts; long-running render processes where the GL context degrades over time; environments using mesa/software rendering with low object limits.","solutions":["Lower render concurrency to reduce the number of live WebGL2 contexts and their GL object allocations","Handle webglcontextlost on the canvas and retry the full render job rather than the individual effect","Verify the rendering environment supports WebGL2 with adequate resource limits (check with a getParameter benchmark)","Restart the render process / browser instance if it has been running long enough to accumulate leaked GL objects"],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"try {\n  await renderMedia({composition, codec: 'h264'});\n} catch (err) {\n  if (err instanceof Error && err.message === 'Failed to create WebGL resources') {\n    // One of VAO, VBO, or texture allocation failed — context is lost or exhausted.\n    // Retry with lower concurrency or a fresh browser instance.\n    await renderMedia({composition, codec: 'h264', concurrency: 2});\n  } else {\n    throw err;\n  }\n}","preventionTips":["Reduce render concurrency to lower the number of simultaneous GL contexts and their object allocations","Register webglcontextlost listeners on render canvases to detect degradation proactively","Periodically restart long-lived render browser instances to reclaim leaked GL objects"],"tags":["webgl","gpu","tv-signal-off","context-loss","resource-exhaustion"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}