{"record":{"id":"0be90e63e15bbff8","repo":"remotion-dev/remotion","slug":"vibrance-shader-link-failed-log-no-log","errorCode":null,"errorMessage":"Vibrance shader link failed: ${log ?? '(no log)'}","messagePattern":"Vibrance shader link failed: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/effects/src/vibrance.ts","lineNumber":135,"sourceCode":"\nconst createProgram = (gl: WebGL2RenderingContext): WebGLProgram => {\n\tconst vertexShader = compileShader(gl, gl.VERTEX_SHADER, VERTEX_SHADER);\n\tconst fragmentShader = compileShader(gl, gl.FRAGMENT_SHADER, FRAGMENT_SHADER);\n\tconst program = gl.createProgram();\n\tif (!program) {\n\t\tthrow new Error('Failed to create vibrance shader program');\n\t}\n\n\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(`Vibrance 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 vibrance 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;","sourceCodeStart":117,"sourceCodeEnd":153,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/vibrance.ts#L117-L153","documentation":"Thrown by the vibrance effect's internal createProgram during setup when gl.linkProgram reports LINK_STATUS === false. The program info log is appended (or '(no log)' if absent). Vibrance compiles and links its own hardcoded GLSL ES 3.00 vertex+fragment shaders, so a link failure means the GPU driver rejected the linked program rather than user-supplied GLSL.","triggerScenarios":"vibrance() effect setup() runs createProgram, which attaches the compiled internal vertex/fragment shaders and calls gl.linkProgram; the driver returns LINK_STATUS false. This occurs on WebGL context loss mid-setup, a driver that rejects the internal GLSL, or a GPU pushed into a degraded state.","commonSituations":"Too many simultaneous WebGL2 contexts in Remotion Studio forcing context loss; headless Chrome (e.g. Remotion Lambda) whose SwiftShader/software GL rejects the program; outdated or buggy GPU drivers; virtual machines without hardware GL acceleration.","solutions":["Reload the page/Studio to reset the WebGL2 context and re-run setup.","Reduce the number of WebGL-backed effects applied concurrently on screen.","Update GPU drivers / enable hardware-accelerated WebGL2 in the browser or headless Chrome flags.","For server rendering, confirm the Chrome build advertises WebGL2 (chrome://gpu) and that software rendering (SwiftShader) is not rejecting the program.","If reproducible, capture the appended info log and report it against @remotion/effects with the GPU/driver details."],"exampleFix":"// before - effect setup throws on context loss, breaking the composition\nimport {vibrance} from '@remotion/effects';\n\nexport const Comp = () => (\n  <VideoEffects effects={[vibrance({amount: 1})]} src={src} />\n);\n\n// after - tolerate setup failure and fall back to the plain source\nimport {vibrance} from '@remotion/effects';\n\nconst tryEffect = (factory) => {\n  try {\n    return factory();\n  } catch (err) {\n    console.warn('effect unavailable, falling back', err);\n    return null;\n  }\n};\n\nexport const Comp = () => {\n  const effect = tryEffect(() => vibrance({amount: 1}));\n  return (\n    <VideoEffects effects={effect ? [effect] : []} src={src} />\n  );\n};","handlingStrategy":"try-catch","validationCode":"// Vibrance shaders are internal library GLSL; no caller validation can prevent a driver link failure.\n// Best pre-check is the host's WebGL2 capability (context loss can still strike later):\nconst supportsWebGL2 = () => {\n  try {\n    const c = document.createElement('canvas');\n    return !!c.getContext('webgl2');\n  } catch {\n    return false;\n  }\n};","typeGuard":null,"tryCatchPattern":"let effect = null;\ntry {\n  effect = vibrance({amount: 1});\n} catch (err) {\n  console.warn('vibrance unavailable on this GPU/context, skipping', err);\n  effect = null; // render the plain source instead\n}","preventionTips":["Keep the number of simultaneously-active WebGL2 effects low to avoid context loss.","Handle the canvas 'webglcontextlost' event and re-create effects on 'webglcontextrestored'.","Confirm WebGL2 is hardware accelerated (chrome://gpu) before relying on shader-heavy effects.","Dispose effects when their sequence is offscreen to free GL program objects."],"tags":["webgl2","shader","gpu","context-loss","vibrance"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}