{"record":{"id":"0f6fbe37205a2d72","repo":"remotion-dev/remotion","slug":"failed-to-create-webgl-program-0f6fbe","errorCode":null,"errorMessage":"Failed to create WebGL program","messagePattern":"Failed to create WebGL program","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/effects/src/fisheye/fisheye-runtime.ts","lineNumber":51,"sourceCode":"\tgl.shaderSource(shader, source);\n\tgl.compileShader(shader);\n\tif (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {\n\t\tconst log = gl.getShaderInfoLog(shader);\n\t\tgl.deleteShader(shader);\n\t\tthrow new Error(`Shader compile failed: ${log ?? '(no log)'}`);\n\t}\n\n\treturn shader;\n};\n\nconst linkProgram = (\n\tgl: WebGL2RenderingContext,\n\tvs: WebGLShader,\n\tfs: WebGLShader,\n): WebGLProgram => {\n\tconst program = gl.createProgram();\n\tif (!program) {\n\t\tthrow new Error('Failed to create WebGL program');\n\t}\n\n\tgl.attachShader(program, vs);\n\tgl.attachShader(program, fs);\n\tgl.linkProgram(program);\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(`Program link failed: ${log ?? '(no log)'}`);\n\t}\n\n\treturn program;\n};\n\nconst createProgram = (\n\tgl: WebGL2RenderingContext,\n\tvertexSource: string,\n\tfragmentSource: string,","sourceCodeStart":33,"sourceCodeEnd":69,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/fisheye/fisheye-runtime.ts#L33-L69","documentation":"Thrown inside linkProgram() in fisheye-runtime.ts when gl.createProgram() returns null (fisheye-runtime.ts:49-52). A null program object means the GL driver would not allocate a program handle — context lost or program-object pool exhausted. Both fisheye shaders have compiled, but there is no program to link them into.","triggerScenarios":"setupFisheye() -> createProgram() -> linkProgram() reaches gl.createProgram() and gets null. This occurs when the WebGL2 context is lost or when leaked programs (from setupFisheye() without cleanupFisheye(), or many effect() instances) have exhausted the driver's program-object budget.","commonSituations":"Apps using fisheye-runtime directly without cleanupFisheye(); long-running Studio leaking programs; compositions with many simultaneous fisheye()/WebGL2 effects; CI on hosts whose GPU process crashed.","solutions":["Render with the Angle backend (--gl=angle / chromiumOptions.gl='angle' / Angle in Studio).","If using fisheye-runtime directly, always pair setupFisheye() with cleanupFisheye() so gl.deleteProgram frees the handle.","Reduce simultaneous WebGL2 effects and reuse identical fisheye() params via calculateKey.","Verify gl.isContextLost() is false and restore the context otherwise.","Update GPU drivers or move to a host with adequate GL resources."],"exampleFix":"// before\nconst program = gl.createProgram();\nif (!program) {\n  throw new Error('Failed to create WebGL program');\n}\n\n// after (ensure cleanup when using the runtime directly)\nconst state = setupFisheye(canvas);\ntry { /* applyFisheye(...) */ } finally { cleanupFisheye(state); }","handlingStrategy":"try-catch","validationCode":"const canAllocateProgram = (gl: WebGL2RenderingContext): boolean => {\n  if (gl.isContextLost()) return false;\n  const probe = gl.createProgram();\n  if (!probe) return false;\n  gl.deleteProgram(probe);\n  return true;\n};","typeGuard":null,"tryCatchPattern":"import {setupFisheye, cleanupFisheye} from '@remotion/effects/fisheye-runtime';\n\nlet state;\ntry {\n  state = setupFisheye(canvas);\n} catch (err) {\n  if (err instanceof Error && err.message === 'Failed to create WebGL program') {\n    // free other fisheye states, retry on Angle\n    throw err;\n  }\n  throw err;\n}\ntry { /* applyFisheye(state, ...) */ } finally { cleanupFisheye(state); }","preventionTips":["When using fisheye-runtime directly, always pair setupFisheye() with cleanupFisheye() (gl.deleteProgram).","Render with Angle (--gl=angle / chromiumOptions.gl='angle').","Limit simultaneous WebGL2 effects; reuse identical fisheye() params via calculateKey.","Handle webglcontextlost and restore before retrying."],"tags":["webgl","program","resource-allocation","gpu","fisheye","setup"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}