BabylonJS/Babylon.js · critical

Unable to create program

Error message

Unable to create program

What it means

When compiling a shader program, context.createProgram() returned null and Babylon throws 'Unable to create program'. WebGL returns null for createProgram when the context is lost or exhausted (too many programs/contexts), so the engine aborts instead of attaching shaders to an invalid program handle.

Source

Thrown at packages/dev/core/src/Engines/engine.pure.ts:631

        const program = super.createShaderProgram(pipelineContext, vertexCode, fragmentCode, defines, context, transformFeedbackVaryings);
        this.onAfterShaderCompilationObservable.notifyObservers(this);

        return program;
    }

    protected override _createShaderProgram(
        pipelineContext: WebGLPipelineContext,
        vertexShader: WebGLShader,
        fragmentShader: WebGLShader,
        context: WebGLRenderingContext,
        transformFeedbackVaryings: Nullable<string[]> = null
    ): WebGLProgram {
        const shaderProgram = context.createProgram();
        pipelineContext.program = shaderProgram;

        if (!shaderProgram) {
            throw new Error("Unable to create program");
        }

        context.attachShader(shaderProgram, vertexShader);
        context.attachShader(shaderProgram, fragmentShader);

        if (this.webGLVersion > 1 && transformFeedbackVaryings) {
            const transformFeedback = this.createTransformFeedback();

            this.bindTransformFeedback(transformFeedback);
            this.setTranformFeedbackVaryings(shaderProgram, transformFeedbackVaryings);
            pipelineContext.transformFeedback = transformFeedback;
        }

        context.linkProgram(shaderProgram);

        if (this.webGLVersion > 1 && transformFeedbackVaryings) {
            this.bindTransformFeedback(null);
        }

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Handle context loss: listen to engine.onContextLost / contextlost event and call engine.restoreDestroyedDualBuffers or reload the engine
  2. Reduce program count: reuse effects/materials, call releaseEffects/releaseCompiledShaders when done
  3. Check for context-lost state before compiling and wait for restore (webglcontextrestored)
  4. Split heavy scenes into separate pages/iframes to avoid hitting context/program limits

Example fix

// before
const effect = engine.createEffect('myShader', ...); // throws if context lost
// after
engine.onContextLostObservable.add(() => console.warn('context lost; pausing renders'));
engine.onContextRestoredObservable.add(() => rebuildShaders());
if (!engine._gl?.isContextLost()) {
  const effect = engine.createEffect('myShader', ...);
}
Defensive patterns

Strategy: try-catch

Validate before calling

const gl = (engine as any)._gl as WebGL2RenderingContext;
if (!gl || gl.isContextLost()) {
  await waitForContextRestored(engine); // listen for webglcontextrestored before compiling
}

Type guard

function glReady(engine: AbstractEngine): engine is AbstractEngine & { _gl: WebGL2RenderingContext } {
  const gl = (engine as any)._gl;
  return !!gl && !gl.isContextLost();
}

Try / catch

try {
  effect = engine.createEffect(name, attrs, uniforms, samplers, defines);
} catch (e) {
  if (e instanceof Error && e.message === 'Unable to create program') {
    await new Promise(res => engine.onContextRestoredObservable.addOnce(res));
    effect = engine.createEffect(name, attrs, uniforms, samplers, defines); // retry after restore
  } else throw e;
}

Prevention

When it happens

Trigger: Creating a shader/program (engine.createShaderProgram path) after a WebGL context loss; too many simultaneously live programs or contexts in the page; GPU driver returning null under resource pressure.

Common situations: Long-running apps that never release shader programs hitting program-count limits; mobile browsers/Safari context loss; running many Babylon engines in one tab and exceeding context limits.

Related errors


AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30). Data as JSON: /api/errors/c68f54fa9cbd6bbf. Report an issue: GitHub.