{"record":{"id":"b5a390c9515e1de2","repo":"remotion-dev/remotion","slug":"exposure-shader-link-failed-log-no-log","errorCode":null,"errorMessage":"Exposure shader link failed: ${log ?? '(no log)'}","messagePattern":"Exposure shader link failed: (.+?)","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"packages/effects/src/exposure.ts","lineNumber":146,"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 exposure 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(`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;","sourceCodeStart":128,"sourceCodeEnd":164,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/exposure.ts#L128-L164","documentation":"Thrown by createProgram() in exposure.ts when gl.getProgramParameter(program, gl.LINK_STATUS) is false after gl.linkProgram() (exposure.ts:143-147). Both shaders compiled, but the linker rejected the program (e.g. incompatible varying declarations, missing uniforms, or a driver linker bug). The InfoLog is included and the half-linked program is deleted.","triggerScenarios":"setupExposure() links VERTEX_SHADER + FRAGMENT_SHADER and LINK_STATUS comes back false. Because both stages are fixed GLSL strings whose varying/uniform contract is fixed (vUv, uSource, uStops), a link failure points at a driver/translator linker bug or a degraded context — not user input.","commonSituations":"Software GL / SwiftShader translators with buggy linkers in headless CI; outdated GPU drivers; a context that is partly broken after a GPU process reset; local edits that desync VERTEX_SHADER and FRAGMENT_SHADER varying declarations.","solutions":["Render with --gl=angle (CLI) / chromiumOptions.gl='angle' (SSR) / Angle (Studio) to use a stable linker.","Read the InfoLog in the error message; if it names a varying/uniform mismatch, verify exposure.ts was not locally edited and that the aPos/aUv attributes match between stages.","Update GPU drivers or switch to a known-good software GL path.","Confirm the context is healthy (gl.isContextLost()) and restore before retrying.","Report the driver linker bug if the GLSL is valid and the InfoLog is nonsensical."],"exampleFix":"// before\ngl.linkProgram(program);\nif (!gl.getProgramParameter(program, gl.LINK_STATUS)) {\n  // linker rejected exposure program\n}\n\n// after (force a stable linker)\n// CLI:  remotion render <comp> --gl=angle\n// SSR:  renderMediaOnLambda({ chromiumOptions: { gl: 'angle' } })","handlingStrategy":"try-catch","validationCode":"// No user input affects linking; both shader stages are fixed strings.\n// Pre-check only context health before setup.\nconst isContextHealthy = (gl: WebGL2RenderingContext): boolean =>\n  !gl.isContextLost();","typeGuard":null,"tryCatchPattern":"try {\n  // apply exposure(); for a custom canvas: const state = setupExposure(canvas);\n} catch (err) {\n  if (err instanceof Error && /Exposure shader link failed/.test(err.message)) {\n    // err.message has the InfoLog; render on Angle and retry.\n    console.error('exposure link failure:', err.message);\n    throw err;\n  }\n  throw err;\n}","preventionTips":["Render with the Angle backend for a stable linker.","Do not locally desync VERTEX_SHADER/FRAGMENT_SHADER varying declarations.","Keep GPU drivers current; report driver linker bugs if GLSL is valid.","Confirm context health (gl.isContextLost()) before setup."],"tags":["webgl","shader","glsl","linker","gpu","exposure","setup"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T23:17:12.415Z"}