BabylonJS/Babylon.js · error

Cannot load file: a valid scene filename or root url was not

Error message

Cannot load file: a valid scene filename or root url was not provided.

What it means

After the scene check, SceneLoader calls GetFileInfo(rootUrl, sceneFilename) to normalize the target into a URL/file descriptor. If both the rootUrl+sceneFilename combination resolve to nothing (empty strings, null filename with no rootUrl), the loader has nothing to fetch and throws this error.

Source

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

}

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);
        }

        let result: ISceneLoaderAsyncResult;
        try {
            result = await toAsyncPlugin(plugin, fileInfo).importMeshAsync(meshNames, scene, data, fileInfo.rootUrl, progressHandler, fileInfo.name);
        } catch (error) {

View on GitHub (pinned to 0592b347b8)

Solutions

  1. Pass a valid rootUrl and sceneFilename, e.g. "assets/" and "scene.glb".
  2. Verify the variable holding the path/filename is non-empty before the call.
  3. If loading from raw data, switch to the data-loading entry point with an explicit pluginExtension instead.

Example fix

// before
await SceneLoader.ImportMeshAsync("", "", "", scene); // throws

// after
await SceneLoader.ImportMeshAsync("", "assets/models/", "scene.glb", scene);
Defensive patterns

Strategy: validation

Validate before calling

if (!rootUrl && !sceneFilename) {
  throw new Error("Provide at least a rootUrl or sceneFilename for the scene to load");
}

Try / catch

try {
  await BABYLON.SceneLoader.ImportMeshAsync("", rootUrl, fileName, scene);
} catch (e) {
  if ((e as Error).message.includes("valid scene filename")) {
    console.error("Empty rootUrl/sceneFilename — check path configuration", { rootUrl, fileName });
  }
}

Prevention

When it happens

Trigger: Calling ImportMeshAsync/AppendAsync with rootUrl = "" and sceneFilename = ""/null, or passing null for both arguments.

Common situations: Building the path from a config value that was empty; forgetting to concatenate the filename; refactoring to data-driven URLs where the key is missing; calling the API with defaults expecting a bundled default model.

Related errors


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