{"record":{"id":"71d9840761026ed4","repo":"remotion-dev/remotion","slug":"failed-to-create-webgl-noise-texture","errorCode":null,"errorMessage":"Failed to create WebGL noise texture","messagePattern":"Failed to create WebGL noise texture","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"packages/effects/src/paper.ts","lineNumber":762,"sourceCode":"\tgl.bindTexture(gl.TEXTURE_2D, texture);\n\tgl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);\n\tgl.texImage2D(\n\t\tgl.TEXTURE_2D,\n\t\t0,\n\t\tgl.RGBA,\n\t\tNOISE_TEXTURE_SIZE,\n\t\tNOISE_TEXTURE_SIZE,\n\t\t0,\n\t\tgl.RGBA,\n\t\tgl.UNSIGNED_BYTE,\n\t\tdata,\n\t);\n};\n\nconst createNoiseTexture = (gl: WebGL2RenderingContext): WebGLTexture => {\n\tconst texture = gl.createTexture();\n\tif (!texture) {\n\t\tthrow new Error('Failed to create WebGL noise texture');\n\t}\n\n\tuploadNoiseTexture(gl, texture, DEFAULT_SEED);\n\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);\n\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);\n\tgl.bindTexture(gl.TEXTURE_2D, null);\n\treturn texture;\n};\n\nconst setupPaper = (target: HTMLCanvasElement): PaperState => {\n\tconst gl = target.getContext('webgl2', {\n\t\tpremultipliedAlpha: true,\n\t\talpha: true,\n\t\tpreserveDrawingBuffer: true,\n\t});\n\tif (!gl) {","sourceCodeStart":744,"sourceCodeEnd":780,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/effects/src/paper.ts#L744-L780","documentation":"Thrown by createNoiseTexture (packages/effects/src/paper.ts:762) when gl.createTexture() returns null while creating the 256×256 noise lookup texture the paper effect samples. Null means context loss, GPU-memory exhaustion, or too many live textures; this is distinct from the source-texture error (777) because it is the dedicated noise LUT.","triggerScenarios":"setupPaper creating the noise LUT on a lost context or under memory pressure; running paper alongside many other texture-heavy effects; rendering with corrupted GL state.","commonSituations":"Low-texture-memory integrated GPUs; leaked textures across sessions; headless software WebGL; GPU process crash mid-render.","solutions":["Ensure cleanup deletes both paper textures between usages and cap concurrent WebGL2 effects.","Render on a GPU host with WebGL enabled in headless Chrome.","Handle context-loss events and re-render after restore."],"exampleFix":"// before\nconst noiseTexture = createNoiseTexture(gl); // createTexture() returned null\n\n// after\nif (gl.isContextLost()) {\n  throw new Error('WebGL2 context lost; cannot create paper noise texture');\n}","handlingStrategy":"try-catch","validationCode":"function canCreatePaperNoiseTexture(): boolean {\n  try {\n    const c = document.createElement('canvas');\n    const gl = c.getContext('webgl2');\n    if (!gl || gl.isContextLost()) return false;\n    const t = gl.createTexture();\n    const ok = !!t;\n    if (t) gl.deleteTexture(t);\n    return ok;\n  } catch {\n    return false;\n  }\n}","typeGuard":null,"tryCatchPattern":"try {\n  scene.push(paper({amount: 1}));\n} catch (err) {\n  if (/Failed to create WebGL noise texture/.test(String(err?.message))) {\n    // noise LUT allocation failed: omit the effect\n  } else throw err;\n}","preventionTips":["Delete both paper textures via cleanup between usages.","Limit concurrent WebGL2 effects and texture-heavy compositions.","Handle context-loss events and render on a GPU host."],"tags":["webgl","gpu","paper","effects","texture","noise","context-loss"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}