BabylonJS/Babylon.js · error · Error

No engine available

Error message

No engine available

What it means

This API creates a new Scene internally from an AbstractEngine. If the engine parameter is null/undefined, the loader cannot construct a Scene and throws immediately. Unlike ImportMesh-style APIs, this entry point owns scene creation, so a live engine is mandatory.

Source

Thrown at packages/dev/core/src/Loading/sceneLoader.ts:1028

        return result;
    } finally {
        scene.removePendingData(loadingToken);
    }
}

// This is the core implementation of load scene
async function loadSceneCoreAsync(
    rootUrl: string,
    sceneFilename: SceneSource = "",
    engine: Nullable<AbstractEngine> = EngineStore.LastCreatedEngine,
    onProgress?: Nullable<(event: ISceneLoaderProgressEvent) => void>,
    pluginExtension?: Nullable<string>,
    name = "",
    pluginOptions: PluginOptions = {}
): Promise<Scene> {
    if (!engine) {
        throw new Error("No engine available");
    }

    const scene = new Scene(engine);
    try {
        await appendSceneCoreAsync(rootUrl, sceneFilename, scene, onProgress, pluginExtension, name, pluginOptions);
    } catch (error) {
        // The scene was created here, so dispose it on failure to avoid leaking the partially loaded scene.
        scene.dispose();
        throw error;
    }
    return scene;
}

/**
 * Load a scene
 * @param source a string that defines the name of the scene file, or starts with "data:" following by the stringified version of the scene, or a File object, or an ArrayBufferView
 * @param engine is the instance of BABYLON.Engine to use to create the scene
 * @param options an object that configures aspects of how the scene is loaded

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Wait for engine initialization (especially WebGPU's async creation) before calling the loader.
  2. Pass the actual AbstractEngine instance, not a scene or a disposed engine.
  3. If you already have a scene, use ImportMeshAsync/AppendScene variants that take a scene instead.

Example fix

// before
let engine; // never initialized
await SceneLoader.LoadAsync(root, "scene.glb", engine); // throws

// after
const engine = new BABYLON.Engine(canvas, true);
await SceneLoader.LoadAsync("assets/", "scene.glb", engine);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!engine) {
  throw new Error("Engine must be created before calling SceneLoader.LoadAsync");
}

Type guard

function isReadyEngine(e: unknown): e is BABYLON.AbstractEngine {
  return !!e && typeof (e as BABYLON.AbstractEngine).getRenderWidth === "function";
}

Try / catch

try {
  await BABYLON.SceneLoader.LoadAsync(root, file, engine);
} catch (e) {
  if ((e as Error).message === "No engine available") {
    console.error("Engine was null/undefined — await engine creation first");
  }
}

Prevention

When it happens

Trigger: Calling SceneLoader.LoadAsync (or the core 'load' variant) with an engine that is null/undefined, e.g. before engine initialization completes.

Common situations: Calling the loader before await engine creation (WebGPU async init); using a disposed engine reference; passing the wrong variable (scene instead of engine) due to argument-order confusion.

Related errors


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