{"record":{"id":"e74f54000b142921","repo":"DavidHDev/react-bits","slug":"failed-to-create-webgl-texture-e74f54","errorCode":null,"errorMessage":"Failed to create WebGL texture.","messagePattern":"Failed to create WebGL texture\\.","errorType":"exception","errorClass":"Error","httpStatus":null,"severity":"error","filePath":"src/ts-tailwind/Components/InfiniteMenu/InfiniteMenu.tsx","lineNumber":472,"sourceCode":"    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,\n  wrapT: number\n): WebGLTexture {\n  const texture = gl.createTexture();\n  if (!texture) {\n    throw new Error('Failed to create WebGL texture.');\n  }\n  gl.bindTexture(gl.TEXTURE_2D, texture);\n  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrapS);\n  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrapT);\n  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter);\n  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter);\n  return texture;\n}\n\ntype UpdateCallback = (deltaTime: number) => void;\n\nclass ArcballControl {\n  private canvas: HTMLCanvasElement;\n  private updateCallback: UpdateCallback;\n\n  public isPointerDown = false;\n  public orientation = quat.create();\n  public pointerRotation = quat.create();","sourceCodeStart":454,"sourceCodeEnd":490,"githubUrl":"https://github.com/DavidHDev/react-bits/blob/c7109dccb42e06592d1d9bc50bc87204697240e2/src/ts-tailwind/Components/InfiniteMenu/InfiniteMenu.tsx#L454-L490","documentation":"Tailwind variant of error 5. createAndSetupTexture throws when gl.createTexture() returns null — lost context or exhausted texture pool — during InfiniteMenu texture setup.","triggerScenarios":"gl.createTexture() returns null at src/ts-tailwind/Components/InfiniteMenu/InfiniteMenu.tsx:467 inside createAndSetupTexture, called from init() or resize.","commonSituations":"webglcontextlost without restoration; many simultaneous WebGL components exhausting the texture pool; GPU process crash; leaked textures from unmount without gl.deleteTexture; mobile/embedded GPUs with tight limits.","solutions":["Listen for 'webglcontextlost'/'webglcontextrestored' and defer allocation while lost.","Dispose textures on unmount with gl.deleteTexture.","Cap the number of live WebGL/InfiniteMenu instances on the page.","Render a fallback path if allocation persistently fails."],"exampleFix":"// before\nconst texture = gl.createTexture();\nif (!texture) throw new Error('Failed to create WebGL texture.');\n\n// after\nuseEffect(() => () => { if (texture) gl.deleteTexture(texture); }, []);","handlingStrategy":"try-catch","validationCode":"function contextHealthy(gl: WebGL2RenderingContext): boolean {\n  return !gl.isContextLost();\n}","typeGuard":"function canCreateTexture(gl: WebGL2RenderingContext): boolean {\n  const probe = gl.createTexture();\n  if (probe) { gl.deleteTexture(probe); return true; }\n  return false;\n}","tryCatchPattern":"canvas.addEventListener('webglcontextlost', (e) => e.preventDefault());\ntry { return createAndSetupTexture(gl, minFilter, magFilter, wrapS, wrapT); }\ncatch (e) {\n  if (e instanceof Error && /WebGL texture/.test(e.message)) return null;\n  throw e;\n}","preventionTips":["Dispose textures with gl.deleteTexture on unmount.","Limit the number of live WebGL/InfiniteMenu instances.","Defer texture creation until after webglcontextrestored.","Provide a fallback path if allocation persistently fails."],"tags":["webgl2","gpu","texture","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"}