DavidHDev/react-bits · critical · Error

No WebGL 2 context!

Error message

No WebGL 2 context!

What it means

The TypeScript variant of error 0. InfiniteMenu.init calls canvas.getContext('webgl2', { antialias, alpha:false }) and throws when null, because the disc instancing pipeline (aInstanceMatrix attribute bound at slot 3) requires WebGL2. No webgl1 fallback exists.

Source

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

  public run(time = 0): void {
    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));
  }

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

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

    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'),

View on GitHub (pinned to c7109dccb4)

Solutions

  1. Probe WebGL2 support before mounting InfiniteMenu and render a fallback if absent.
  2. In tests, use a WebGL2-capable headless browser (Chromium + SwiftShader/ANGLE) or mock the component.
  3. Update GPU drivers / browser; confirm chrome://gpu lists WebGL2 as hardware accelerated.
  4. Enable hardware acceleration in the host browser/WebView.

Example fix

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

// after
const gl = this.canvas.getContext('webgl2', { antialias: true, alpha: false });
if (!gl) { onInit?.(new Error('No WebGL 2 context!')); return; } // caller renders fallback
Defensive patterns

Strategy: validation

Validate before calling

function supportsWebGL2(): boolean {
  try { return !!document.createElement('canvas').getContext('webgl2'); }
  catch { return false; }
}
if (!supportsWebGL2()) return <FallbackMenu />;

Type guard

function hasWebGL2(canvas: HTMLCanvasElement): boolean {
  return !!canvas.getContext('webgl2', { antialias: true, alpha: false });
}

Prevention

When it happens

Trigger: getContext('webgl2') returns null at src/ts-default/Components/InfiniteMenu/InfiniteMenu.tsx:766-770 during InfiniteMenu.init, before discProgram is created.

Common situations: jsdom/Vitest test environments; outdated browsers without WebGL2 (old Safari/iOS, embedded WebViews); GPU drivers on the WebGL2 blocklist; software renderers exposing only webgl1; CI without a WebGL2-capable headless browser.

Related errors


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