DavidHDev/react-bits · error · Error

Failed to create WebGL buffer.

Error message

Failed to create WebGL buffer.

What it means

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.

Source

Thrown at src/ts-tailwind/Components/InfiniteMenu/InfiniteMenu.tsx:449

  return va;
}

function resizeCanvasToDisplaySize(canvas: HTMLCanvasElement): boolean {
  const dpr = Math.min(2, window.devicePixelRatio || 1);
  const displayWidth = Math.round(canvas.clientWidth * dpr);
  const displayHeight = Math.round(canvas.clientHeight * dpr);
  const needResize = canvas.width !== displayWidth || canvas.height !== displayHeight;
  if (needResize) {
    canvas.width = displayWidth;
    canvas.height = displayHeight;
  }
  return needResize;
}

function makeBuffer(gl: WebGL2RenderingContext, sizeOrData: number | ArrayBufferView, usage: number): WebGLBuffer {
  const buf = gl.createBuffer();
  if (!buf) {
    throw new Error('Failed to create WebGL buffer.');
  }
  gl.bindBuffer(gl.ARRAY_BUFFER, buf);

  if (typeof sizeOrData === 'number') {
    gl.bufferData(gl.ARRAY_BUFFER, sizeOrData, usage);
  } else {
    gl.bufferData(gl.ARRAY_BUFFER, sizeOrData, usage);
  }

  gl.bindBuffer(gl.ARRAY_BUFFER, null);
  return buf;
}

function createAndSetupTexture(
  gl: WebGL2RenderingContext,
  minFilter: number,
  magFilter: number,
  wrapS: number,

View on GitHub (pinned to c7109dccb4)

Solutions

  1. Handle 'webglcontextlost'/'webglcontextrestored' and skip allocation while lost.
  2. Delete buffers on unmount (gl.deleteBuffer) to prevent pool exhaustion.
  3. Limit concurrent InfiniteMenu/WebGL instances on the page.
  4. On persistent failure, render a fallback and report the unsupported environment.

Example fix

// before
const buf = gl.createBuffer();
if (!buf) throw new Error('Failed to create WebGL buffer.');

// after
canvas.addEventListener('webglcontextlost', e => e.preventDefault());
canvas.addEventListener('webglcontextrestored', reinit);
if (contextLost) return null;
const buf = gl.createBuffer();
if (!buf) throw new Error('Failed to create WebGL buffer.');
Defensive patterns

Strategy: try-catch

Validate before calling

function contextHealthy(gl: WebGL2RenderingContext): boolean {
  return !gl.isContextLost();
}

Type guard

function hasBufferPool(gl: WebGL2RenderingContext): boolean {
  const probe = gl.createBuffer();
  if (probe) { gl.deleteBuffer(probe); return true; }
  return false;
}

Try / catch

canvas.addEventListener('webglcontextlost', (e) => e.preventDefault());
try { return makeBuffer(gl, sizeOrData, usage); }
catch (e) {
  if (e instanceof Error && /WebGL buffer/.test(e.message)) return null;
  throw e;
}

Prevention

When it happens

Trigger: gl.createBuffer() returns null at src/ts-tailwind/Components/InfiniteMenu/InfiniteMenu.tsx:446 inside makeBuffer.

Common situations: 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.

Related errors


AI-assisted analysis of DavidHDev/react-bits@c7109dccb4 (2026-08-13). Data as JSON: /api/errors/f402ea2150599743. Report an issue: GitHub.