BabylonJS/Babylon.js · error

No scene available to import mesh to

Error message

No scene available to import mesh to

What it means

ImportMesh-style core APIs need a Scene instance to add imported meshes/nodes to. This guard throws when the scene parameter is null/undefined at the start of the import routine, before any file info is resolved.

Source

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

 * @returns The loaded list of imported meshes, particle systems, skeletons, and animation groups
 */
export async function ImportMeshAsync(source: SceneSource, scene: Scene, options?: ImportMeshOptions): Promise<ISceneLoaderAsyncResult> {
    const { meshNames, rootUrl = "", onProgress, pluginExtension, name, pluginOptions } = options ?? {};
    return await importMeshCoreAsync(meshNames, rootUrl, source, scene, onProgress, pluginExtension, name, pluginOptions);
}

async function importMeshCoreAsync(
    meshNames: string | readonly string[] | null | undefined,
    rootUrl: string,
    sceneFilename: SceneSource = "",
    scene: Nullable<Scene> = EngineStore.LastCreatedScene,
    onProgress?: Nullable<(event: ISceneLoaderProgressEvent) => void>,
    pluginExtension?: Nullable<string>,
    name = "",
    pluginOptions: PluginOptions = {}
): Promise<ISceneLoaderAsyncResult> {
    if (!scene) {
        throw new Error("No scene available to import mesh to");
    }

    const fileInfo = GetFileInfo(rootUrl, sceneFilename);
    if (!fileInfo) {
        throw new Error("Cannot load file: a valid scene filename or root url was not provided.");
    }

    const loadingToken = {};
    scene.addPendingData(loadingToken);

    const progressHandler = wrapProgress(onProgress);

    try {
        const { plugin, data, responseURL } = await loadDataAsync(fileInfo, scene, progressHandler, pluginExtension ?? null, name, pluginOptions);

        if (plugin.rewriteRootURL) {
            fileInfo.rootUrl = plugin.rewriteRootURL(fileInfo.rootUrl, responseURL);
        }

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Create the scene first (new Scene(engine)) and pass it to the import call.
  2. If you want the engine-only convenience API, use SceneLoader.LoadAsync / AppendAsync which create the scene internally.
  3. Check that the scene has not been disposed and the variable holds a Scene instance before importing.

Example fix

// before
await SceneLoader.ImportMeshAsync("", root, "model.glb", null); // throws

// after
const scene = new BABYLON.Scene(engine);
await SceneLoader.ImportMeshAsync("", root, "model.glb", scene);
Defensive patterns

Strategy: type-guard

Validate before calling

if (!scene || scene.isDisposed) {
  throw new Error("ImportMeshAsync requires a live Scene instance");
}

Type guard

function isUsableScene(s: unknown): s is BABYLON.Scene {
  return s instanceof BABYLON.Scene && !s.isDisposed;
}

Try / catch

try {
  await BABYLON.SceneLoader.ImportMeshAsync("", root, file, scene);
} catch (e) {
  if ((e as Error).message === "No scene available to import mesh to") {
    console.error("Scene was null — initialize the scene before importing");
  }
}

Prevention

When it happens

Trigger: Calling SceneLoader.ImportMeshAsync / appendScene core path with scene explicitly passed as null or an undefined variable.

Common situations: Awaiting an engine/scene creation promise and calling import before it resolves; a variable shadowing or clearing the scene reference after disposal; passing arguments in the wrong order so scene is undefined.

Related errors


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