BabylonJS/Babylon.js · error
runTask is not implemented
Error message
runTask is not implemented
What it means
This is the abstract base-class implementation of AbstractAssetTask.runTask. The library throws it when a task is run that never overrode runTask, i.e. a custom or built-in task class forgot to implement the actual loading logic. AssetsManager calls runTask for each task when the AssetsManager.load()/processAsync runs.
Source
Thrown at packages/dev/core/src/Misc/assetsManager.ts:134
scene,
() => {
this._onDoneCallback(onSuccess, onError);
},
(msg, exception) => {
this._onErrorCallback(onError, msg, exception);
}
);
}
/**
* Execute the current task
* @param scene defines the scene where you want your assets to be loaded
* @param onSuccess is a callback called when the task is successfully executed
* @param onError is a callback called if an error occurs
*/
// eslint-disable-next-line @typescript-eslint/no-unused-vars
public runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
throw new Error("runTask is not implemented");
}
/**
* Reset will set the task state back to INIT, so the next load call of the assets manager will execute this task again.
* This can be used with failed tasks that have the reason for failure fixed.
*/
public reset() {
this._taskState = AssetTaskState.INIT;
}
private _onErrorCallback(onError: (message?: string, exception?: any) => void, message?: string, exception?: any) {
this._taskState = AssetTaskState.ERROR;
this._errorObject = {
message: message,
exception: exception,
};
View on GitHub (pinned to 0592b347b8)
Solutions
- Create a subclass and override runTask(scene, onSuccess, onError), calling onSuccess() on success or onError(message, exception) on failure
- If you meant to use a built-in loader, instantiate the concrete task type (e.g. TextFileAssetTask, ImageAssetTask) instead of the abstract base
- Check the override signature matches exactly: public runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void)
Example fix
// before
class MyTask extends AbstractAssetTask {
// no runTask override
}
// after
class MyTask extends AbstractAssetTask {
public runTask(scene: Scene, onSuccess: () => void, onError: (message?: string, exception?: any) => void) {
try {
this._data = doLoad();
onSuccess();
} catch (e) {
onError('load failed', e);
}
}
} Defensive patterns
Strategy: validation
Validate before calling
if (typeof (task as any).runTask !== 'function' || task.constructor === AbstractAssetTask) {
throw new TypeError('Task must be a concrete subclass that overrides runTask');
} Type guard
function hasRunTask(t: AbstractAssetTask): t is AbstractAssetTask & { runTask(scene: Scene, onSuccess: () => void, onError: (m?: string, e?: any) => void): void } {
return t.runTask !== AbstractAssetTask.prototype.runTask;
} Try / catch
try {
assetsManager.load();
} catch (e) {
if (e instanceof Error && e.message === 'runTask is not implemented') {
console.error('Task class does not override runTask:', e);
}
} Prevention
- Always subclass a concrete task type or override runTask in custom tasks
- Use TypeScript abstract members so missing overrides fail at compile time
- Add a unit test that runs every custom task through AssetsManager.load
When it happens
Trigger: Calling AssetsManager.load()/run() with a task instance whose class does not override runTask — e.g. instantiating AbstractAssetTask (or a base task) directly, or a custom task subclass that overrides only onSuccess/onError but not runTask.
Common situations: Writing a custom asset task and forgetting to override runTask; refactoring that renamed the override so it no longer matches the signature; using a very old task class from a version whose runTask was renamed.
Related errors
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/f69f25f5f36a4848.
Report an issue: GitHub.