{"record":{"id":"f402ea2150599743","repo":"DavidHDev/react-bits","slug":"failed-to-create-webgl-buffer-f402ea","errorCode":null,"errorMessage":"Failed to create WebGL buffer.","messagePattern":"Failed to create WebGL buffer\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/ts-tailwind/Components/InfiniteMenu/InfiniteMenu.tsx","lineNumber":449,"sourceCode":"  return va;\n}\n\nfunction resizeCanvasToDisplaySize(canvas: HTMLCanvasElement): boolean {\n  const dpr = Math.min(2, window.devicePixelRatio || 1);\n  const displayWidth = Math.round(canvas.clientWidth * dpr);\n  const displayHeight = Math.round(canvas.clientHeight * dpr);\n  const needResize = canvas.width !== displayWidth || canvas.height !== displayHeight;\n  if (needResize) {\n    canvas.width = displayWidth;\n    canvas.height = displayHeight;\n  }\n  return needResize;\n}\n\nfunction makeBuffer(gl: WebGL2RenderingContext, sizeOrData: number | ArrayBufferView, usage: number): WebGLBuffer {\n  const buf = gl.createBuffer();\n  if (!buf) {\n    throw new Error('Failed to create WebGL buffer.');\n  }\n  gl.bindBuffer(gl.ARRAY_BUFFER, buf);\n\n  if (typeof sizeOrData === 'number') {\n    gl.bufferData(gl.ARRAY_BUFFER, sizeOrData, usage);\n  } else {\n    gl.bufferData(gl.ARRAY_BUFFER, sizeOrData, usage);\n  }\n\n  gl.bindBuffer(gl.ARRAY_BUFFER, null);\n  return buf;\n}\n\nfunction createAndSetupTexture(\n  gl: WebGL2RenderingContext,\n  minFilter: number,\n  magFilter: number,\n  wrapS: number,","sourceCodeStart":431,"sourceCodeEnd":467,"githubUrl":"https://github.com/DavidHDev/react-bits/blob/c7109dccb42e06592d1d9bc50bc87204697240e2/src/ts-tailwind/Components/InfiniteMenu/InfiniteMenu.tsx#L431-L467","documentation":"Tailwind variant of error 4. makeBuffer throws when gl.createBuffer() returns null — a lost WebGL context or exhausted GL object pool. Called during InfiniteMenu.init to allocate vertex/instance buffers.","triggerScenarios":"gl.createBuffer() returns null at src/ts-tailwind/Components/InfiniteMenu/InfiniteMenu.tsx:446 inside makeBuffer.","commonSituations":"webglcontextlost fired and not yet restored; too many WebGL components/instances exhausting the GL object pool; GPU process crash; rapid mount/unmount leaking buffers (missing deleteBuffer); mobile GPUs with small pools.","solutions":["Handle 'webglcontextlost'/'webglcontextrestored' and skip allocation while lost.","Delete buffers on unmount (gl.deleteBuffer) to prevent pool exhaustion.","Limit concurrent InfiniteMenu/WebGL instances on the page.","On persistent failure, render a fallback and report the unsupported environment."],"exampleFix":"// before\nconst buf = gl.createBuffer();\nif (!buf) throw new Error('Failed to create WebGL buffer.');\n\n// after\ncanvas.addEventListener('webglcontextlost', e => e.preventDefault());\ncanvas.addEventListener('webglcontextrestored', reinit);\nif (contextLost) return null;\nconst buf = gl.createBuffer();\nif (!buf) throw new Error('Failed to create WebGL buffer.');","handlingStrategy":"try-catch","validationCode":"function contextHealthy(gl: WebGL2RenderingContext): boolean {\n  return !gl.isContextLost();\n}","typeGuard":"function hasBufferPool(gl: WebGL2RenderingContext): boolean {\n  const probe = gl.createBuffer();\n  if (probe) { gl.deleteBuffer(probe); return true; }\n  return false;\n}","tryCatchPattern":"canvas.addEventListener('webglcontextlost', (e) => e.preventDefault());\ntry { return makeBuffer(gl, sizeOrData, usage); }\ncatch (e) {\n  if (e instanceof Error && /WebGL buffer/.test(e.message)) return null;\n  throw e;\n}","preventionTips":["Handle webglcontextlost/webglcontextrestored; don't allocate while lost.","Delete buffers on unmount to prevent pool exhaustion.","Cap concurrent WebGL/InfiniteMenu instances.","Retry once after restore before surfacing failure."],"tags":["webgl2","gpu","buffer","context-loss","resource-limits","tailwind","infinitemenu"],"backgroundTag":null,"analyzedSha":"c7109dccb42e06592d1d9bc50bc87204697240e2","analyzedAt":"2026-08-13T02:32:07.327Z","schemaVersion":2},"datasetVersion":"2026-08-13T04:17:16.726Z"}