DavidHDev/react-bits · error · Error

Failed to create WebGL buffer.

Error message

Failed to create WebGL buffer.

What it means

makeBuffer calls gl.createBuffer(); when the GL implementation returns null it throws. createBuffer returns null on context loss (the webglcontextlost event has invalidated the context) or when the implementation has exhausted its object pool. This is a resource/context-lifecycle failure, not a usage bug.

Source

Thrown at src/ts-default/Components/InfiniteMenu/InfiniteMenu.tsx:451

  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. Listen for 'webglcontextlost' on the canvas and stop/skip re-init until 'webglcontextrestored' fires.
  2. Reduce the number of simultaneously mounted WebGL components / disc instances to stay under GL object limits.
  3. Dispose buffers and call gl.deleteBuffer when the component unmounts to free the pool.
  4. Retry allocation once after a short delay in case the loss was transient; surface a fallback UI if it persists.

Example fix

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

// after
canvas.addEventListener('webglcontextlost', e => { e.preventDefault(); contextLost = true; }, false);
canvas.addEventListener('webglcontextrestored', () => { contextLost = false; reinit(); }, false);
if (contextLost) return null; // skip allocation while context is lost
const buf = gl.createBuffer();
if (!buf) throw new Error('Failed to create WebGL buffer.');
Defensive patterns

Strategy: try-catch

Validate before calling

// check context health before allocating
function contextHealthy(gl: WebGL2RenderingContext): boolean {
  // a lost context returns this constant from anygetError
  return gl.isContextLost && !gl.isContextLost();
}

Type guard

function hasBufferPool(gl: WebGL2RenderingContext): boolean {
  // createBuffer returns null on lost context / exhausted pool
  const probe = gl.createBuffer();
  if (probe) { gl.deleteBuffer(probe); return true; }
  return false;
}

Try / catch

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

Prevention

When it happens

Trigger: gl.createBuffer() returns null at src/ts-default/Components/InfiniteMenu/InfiniteMenu.tsx:448 inside makeBuffer, which is called repeatedly during InfiniteMenu.init to allocate vertex/instance buffers. Triggered right after a context-loss event or when GL object limits are hit.

Common situations: Too many InfiniteMenu instances (or other WebGL components) on one page exceeding the browser's live GL object/context limits; GPU process crash mid-session; tab backgrounded and context lost then a resize triggers re-init; mobile GPUs with small object pools.

Related errors


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