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

  1. Call and await `InitRecast()` (imported from @babylonjs/core or the addons navigation module) before any other navigation API.
  2. Gate all navigation usage on the init promise: `await recastInitPromise;` at app startup.
  3. 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

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


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