DavidHDev/react-bits · critical · Error

No WebGL 2 context!

Error message

No WebGL 2 context!

What it means

Thrown by InfiniteMenu.#init after canvas.getContext('webgl2', ...) returns null. The menu is built on WebGL2-only features (instanced arrays via aInstanceMatrix, float color buffers), so a null context means the component cannot render at all and aborts during construction. This is a hard capability gate, not a recoverable render glitch.

Source

Thrown at src/content/Components/InfiniteMenu/InfiniteMenu.jsx:637

  }

  run(time = 0) {
    this.#deltaTime = Math.min(32, time - this.#time);
    this.#time = time;
    this.#deltaFrames = this.#deltaTime / this.TARGET_FRAME_DURATION;
    this.#frames += this.#deltaFrames;

    this.#animate(this.#deltaTime);
    this.#render();

    requestAnimationFrame(t => this.run(t));
  }

  #init(onInit) {
    this.gl = this.canvas.getContext('webgl2', { antialias: true, alpha: false });
    const gl = this.gl;
    if (!gl) {
      throw new Error('No WebGL 2 context!');
    }

    this.viewportSize = vec2.fromValues(this.canvas.clientWidth, this.canvas.clientHeight);
    this.drawBufferSize = vec2.clone(this.viewportSize);

    this.discProgram = createProgram(gl, [discVertShaderSource, discFragShaderSource], null, {
      aModelPosition: 0,
      aModelNormal: 1,
      aModelUvs: 2,
      aInstanceMatrix: 3
    });

    this.discLocations = {
      aModelPosition: gl.getAttribLocation(this.discProgram, 'aModelPosition'),
      aModelUvs: gl.getAttribLocation(this.discProgram, 'aModelUvs'),
      aInstanceMatrix: gl.getAttribLocation(this.discProgram, 'aInstanceMatrix'),
      uWorldMatrix: gl.getUniformLocation(this.discProgram, 'uWorldMatrix'),
      uViewMatrix: gl.getUniformLocation(this.discProgram, 'uViewMatrix'),

View on GitHub (pinned to c7109dccb4)

Solutions

  1. Confirm support first: open chrome://gpu (or about:support in Firefox) and verify 'WebGL2' is listed as Hardware accelerated.
  2. Update GPU drivers / browser to a WebGL2-capable version; on Linux prefer the proprietary/Mesa driver over llvmpipe.
  3. In tests/jsdom, skip or mock the component rather than instantiating it, since jsdom provides no webgl2 context.
  4. Feature-detect before mounting and render a static fallback when WebGL2 is absent (see exampleFix).

Example fix

// before
import InfiniteMenu from './InfiniteMenu';
new InfiniteMenu({ canvas }); // throws if no webgl2

// after
const probe = document.createElement('canvas').getContext('webgl2');
if (probe) {
  new InfiniteMenu({ canvas });
} else {
  // render a plain HTML/CSS menu fallback
}
Defensive patterns

Strategy: validation

Validate before calling

function supportsWebGL2(): boolean {
  try {
    return !!document.createElement('canvas').getContext('webgl2');
  } catch {
    return false;
  }
}
// before mounting InfiniteMenu:
if (!supportsWebGL2()) { renderFallbackMenu(); }

Type guard

// runtime capability guard (not a type narrowing, but the equivalent gate)
const webgl2Available: boolean =
  typeof HTMLCanvasElement !== 'undefined' &&
  !!document.createElement('canvas').getContext('webgl2');

// if you wrap the component:
function isWebGL2Canvas(canvas: HTMLCanvasElement): canvas is HTMLCanvasElement & { getContext(c: 'webgl2'): WebGL2RenderingContext } {
  return !!canvas.getContext('webgl2');
}

Prevention

When it happens

Trigger: Instantiating the InfiniteMenu class on a canvas whose browser/driver exposes no 'webgl2' context type. Concretely: this.canvas.getContext('webgl2', { antialias: true, alpha: false }) === null at src/content/Components/InfiniteMenu/InfiniteMenu.jsx:637.

Common situations: Headless test runners (jsdom in Jest/Vitest) that have no real GL backend; users on outdated mobile browsers (pre-2020 Safari, older Android Chrome); machines with blacklisted GPU drivers where the browser disables WebGL2 (chrome://gpu shows 'WebGL2: Hardware unavailable'); software/swiftshader renderers that only expose webgl1.

Related errors


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