BabylonJS/Babylon.js · error
GaussianSplattingDownloadManager has been disposed.
Error message
GaussianSplattingDownloadManager has been disposed.
What it means
The GaussianSplattingDownloadManager coordinates shared/pending SPLAT file downloads and can be disposed via its dispose() method. Once disposed, loadFileAsync refuses all new work with this error. It signals use-after-dispose: the manager's internal state (pending tasks, abort controllers) has been torn down and cannot accept downloads.
Source
Thrown at packages/dev/loaders/src/SPLAT/gaussianSplattingDownloadManager.ts:99
}
/**
* Whether there are no downloads queued or in flight.
*/
public get isIdle(): boolean {
return this._pending.size === 0;
}
/**
* Downloads a file as an `ArrayBuffer`, queued behind the concurrency cap and retried on failure.
* Concurrent requests for the same URL resolve from a single shared download.
* @param url the file URL to download
* @param groupId optional group tag so related downloads can be cancelled together via {@link cancelGroup}
* @returns a promise resolving with the downloaded bytes
*/
public async loadFileAsync(url: string, groupId?: DownloadGroupId): Promise<ArrayBuffer> {
if (this._disposed) {
throw new Error("GaussianSplattingDownloadManager has been disposed.");
}
const existing = this._pending.get(url);
if (existing) {
return await existing.promise;
}
const task: IDownloadTask = {
url,
groupId,
settled: false,
cancelled: false,
started: false,
slotReleased: false,
} as IDownloadTask;
task.promise = new Promise<ArrayBuffer>((resolve, reject) => {
task.resolve = resolve;
task.reject = reject;
});
this._pending.set(url, task);
View on GitHub (pinned to 0592b347b8)
Solutions
- Create a new GaussianSplattingDownloadManager instance after disposing the previous one.
- Restructure code so dispose() is only called after all loadFileAsync promises settle.
- Guard call sites with a disposed check or a flag reset when reinitializing the scene.
- If using framework lifecycle hooks, bind the manager's lifetime to the engine/scene instead of a component that unmounts early.
Example fix
// before manager.dispose(); await manager.loadFileAsync(url); // throws // after manager.dispose(); manager = new GaussianSplattingDownloadManager(); await manager.loadFileAsync(url);
Defensive patterns
Strategy: try-catch
Validate before calling
let manager: GaussianSplattingDownloadManager | null = getManager();
if (!manager) {
manager = new GaussianSplattingDownloadManager(); // recreate if disposed
} Type guard
function isManagerUsable(m: GaussianSplattingDownloadManager | null): m is GaussianSplattingDownloadManager {
return m !== null && !m.isDisposed; // track via your own flag if not exposed
} Try / catch
try {
const data = await manager.loadFileAsync(url, groupId);
} catch (e) {
if (String(e.message).includes("has been disposed")) {
manager = new GaussianSplattingDownloadManager();
return manager.loadFileAsync(url, groupId);
}
throw e;
} Prevention
- Never call dispose() while loadFileAsync promises are still pending.
- Tie the manager's lifetime to the engine/scene, not to a short-lived component.
- Recreate the manager after disposal instead of reusing the instance.
- Track in-flight downloads with cancelGroup so disposal doesn't race active loads.
When it happens
Trigger: Calling loadFileAsync after GaussianSplattingDownloadManager.dispose() was invoked, e.g. loading another splat file with the same manager instance after a scene/mesh was disposed.
Common situations: Reusing a loader/manager across scene reloads; disposing a GaussianSplatting mesh then attempting to stream another file through the same manager; race between an async load and scene disposal.
Related errors
- GaussianSplattingStream: streaming part was not reserved.
- There is no NavMesh generated.
- There is no TileCache generated.
- No volume subnode
- Disconnect failed
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/217536d9f40b2d30.
Report an issue: GitHub.