BabylonJS/Babylon.js · error · Error
Recast is not initialized. Please call InitRecast first.
Error message
Recast is not initialized. Please call InitRecast first.
What it means
The navigation module keeps a module-level `_Recast` handle to the recast-navigation-js WASM library, set only by calling InitRecast (which loads the WASM). GetRecast throws when the handle is still unset, i.e. any navigation API is used before initialization.
Source
Thrown at packages/dev/addons/src/navigation/factory/common.ts:13
import { _LoadScriptModuleAsync } from "core/Misc/tools.internals";
import { type Nullable } from "core/types";
import { type RecastInjection } from "../types";
/**
* Gets the RecastInjection instance (reference to the recast-navigation-js library).
* @returns The RecastInjection instance
* @throws Error if Recast is not initialized
*/
export function GetRecast(): RecastInjection {
if (!_Recast) {
throw new Error("Recast is not initialized. Please call InitRecast first.");
}
return _Recast;
}
/**
* Sets the RecastInjection instance (reference to the recast-navigation-js library).
* @param recast The RecastInjection instance to set
*/
export function SetRecast(recast: RecastInjection) {
_Recast = recast;
}
/**
* Reference to the recast-navigation-js library
*/
let _Recast: RecastInjection;
/**View on GitHub (pinned to 0592b347b8)
Solutions
- Call and await `InitRecast()` (imported from @babylonjs/core or the addons navigation module) before any other navigation API.
- Gate all navigation usage on the init promise: `await recastInitPromise;` at app startup.
- If init already exists, check that it succeeded and that the correct WASM build/import path was used.
Example fix
// before
const plugin = new RecastJSPlugin(); // throws: Recast not initialized
// after
import { InitRecast } from "@babylonjs/addons";
await InitRecast();
const plugin = new RecastJSPlugin(); Defensive patterns
Strategy: validation
Validate before calling
let recastReady = false;
async function ensureRecast() {
if (!recastReady) { await InitRecast(); recastReady = true; }
}
await ensureRecast(); // before any navigation API Type guard
let recastInitialized = false;
export const isRecastInitialized = (): boolean => recastInitialized;
if (!isRecastInitialized()) { /* block navigation usage */ } Try / catch
try {
plugin = new RecastJSPlugin(scene);
} catch (e) {
if (String(e).includes("InitRecast")) {
await InitRecast();
plugin = new RecastJSPlugin(scene);
} else throw e;
} Prevention
- Always `await InitRecast()` once at app startup before navigation code runs.
- Keep a single shared init promise instead of multiple init calls.
- Import navigation modules only after (or gated behind) initialization.
When it happens
Trigger: Calling GetRecast directly, or any navigation API that depends on it (RecastJSPlugin construction, navmesh creation/recast helpers, CreateDefaultTileCacheMeshProcess) without first calling `await InitRecast()` (or InitRecast with the appropriate WASM import).
Common situations: Forgetting the async init step when migrating from the old bundled RecastJSPlugin; using navigation code in a module that loads before the async InitRecast() promise resolves; building the WASM path incorrectly so init silently never ran.
Related errors
- Unable to deserialize NavMesh.
- Unable to generateSoloNavMesh: ${result.error}
- Unable to generate navMesh: ${e}
- Unable to generate navMesh/tileCache: ${e}
- There is no NavMesh generated.
AI-assisted analysis of BabylonJS/Babylon.js@0592b347b8 (2026-08-30).
Data as JSON: /api/errors/11020ea9de19724e.
Report an issue: GitHub.