{"record":{"id":"3bb7ac5660fcda0f","repo":"DavidHDev/react-bits","slug":"unable-to-initialize-webgl-3bb7ac","errorCode":null,"errorMessage":"Unable to initialize WebGL.","messagePattern":"Unable to initialize WebGL\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"critical","filePath":"src/ts-tailwind/Animations/SplashCursor/SplashCursor.tsx","lineNumber":133,"sourceCode":"\n    function getWebGLContext(canvas: HTMLCanvasElement) {\n      const params = {\n        alpha: true,\n        depth: false,\n        stencil: false,\n        antialias: false,\n        preserveDrawingBuffer: false\n      };\n\n      let gl = canvas.getContext('webgl2', params) as WebGL2RenderingContext | null;\n\n      if (!gl) {\n        gl = (canvas.getContext('webgl', params) ||\n          canvas.getContext('experimental-webgl', params)) as WebGL2RenderingContext | null;\n      }\n\n      if (!gl) {\n        throw new Error('Unable to initialize WebGL.');\n      }\n\n      const isWebGL2 = 'drawBuffers' in gl;\n\n      let supportLinearFiltering = false;\n      let halfFloat: OES_texture_half_float | null = null;\n\n      if (isWebGL2) {\n        (gl as WebGL2RenderingContext).getExtension('EXT_color_buffer_float');\n        supportLinearFiltering = !!(gl as WebGL2RenderingContext).getExtension('OES_texture_float_linear');\n      } else {\n        halfFloat = gl.getExtension('OES_texture_half_float');\n        supportLinearFiltering = !!gl.getExtension('OES_texture_half_float_linear');\n      }\n\n      gl.clearColor(0, 0, 0, 1);\n\n      const halfFloatTexType = isWebGL2","sourceCodeStart":115,"sourceCodeEnd":151,"githubUrl":"https://github.com/DavidHDev/react-bits/blob/c7109dccb42e06592d1d9bc50bc87204697240e2/src/ts-tailwind/Animations/SplashCursor/SplashCursor.tsx#L115-L151","documentation":"Tailwind variant of error 2. SplashCursor.getWebGLContext attempts webgl2 then webgl then experimental-webgl; this throw fires only when every context type is unavailable, meaning no WebGL at all.","triggerScenarios":"getContext('webgl2'), getContext('webgl'), and getContext('experimental-webgl') all return null at src/ts-tailwind/Animations/SplashCursor/SplashCursor.tsx:125-133.","commonSituations":"jsdom/happy-dom with no GL backend; WebGL disabled via browser flags or driver blocklist; locked-down kiosks; extremely old browsers; environments with no GL driver whatsoever.","solutions":["Probe for any GL context before mounting SplashCursor and skip otherwise.","Use a real headless Chromium with SwiftShader/ANGLE for automated tests.","Enable WebGL / update drivers in the user's browser (verify chrome://gpu).","Render a non-WebGL cursor fallback when no GL context exists."],"exampleFix":"// before\nconst { gl, ext } = getWebGLContext(canvas);\n\n// after\nfunction anyGL() {\n  const c = document.createElement('canvas');\n  return !!(c.getContext('webgl2') || c.getContext('webgl') || c.getContext('experimental-webgl'));\n}\nif (!anyGL()) return null;","handlingStrategy":"validation","validationCode":"function supportsAnyWebGL(): boolean {\n  const c = document.createElement('canvas');\n  try {\n    return !!(c.getContext('webgl2') || c.getContext('webgl') || c.getContext('experimental-webgl'));\n  } catch { return false; }\n}","typeGuard":"function getGL(canvas: HTMLCanvasElement): WebGLRenderingContext | WebGL2RenderingContext | null {\n  return (canvas.getContext('webgl2') || canvas.getContext('webgl') || canvas.getContext('experimental-webgl')) as WebGLRenderingContext | null;\n}","tryCatchPattern":null,"preventionTips":["Detect any WebGL before mounting the tailwind SplashCursor.","Use a GL-capable headless browser in tests, not jsdom.","Render a plain cursor fallback when no GL context exists.","Confirm WebGL isn't blocklisted (chrome://gpu)."],"tags":["webgl","gpu","context","initialization","browser-support","tailwind","splashcursor"],"backgroundTag":null,"analyzedSha":"c7109dccb42e06592d1d9bc50bc87204697240e2","analyzedAt":"2026-08-13T02:32:07.327Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}